ctkDcmSCU.h 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. /*
  2. *
  3. * Copyright (C) 2008-2011, 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. * Last Update: $Author: uli $
  21. * Update Date: $Date: 2011-10-10 14:01:29 $
  22. * CVS/RCS Revision: $Revision: 1.39 $
  23. * Status: $State: Exp $
  24. *
  25. * CVS/RCS Log at end of file
  26. *
  27. */
  28. ///
  29. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  30. // Note: this class was added at the CTK Hackfest as a copy of the
  31. // DcmSCU class in the then current dcmtk
  32. // http://git.dcmtk.org/dcmtk.git
  33. // 90c7ac4120aec925a41d8742d685fe1671a4a343
  34. //
  35. // http://www.commontk.org/index.php/CTK-Hackfest-Nov-2011
  36. //
  37. // When this code is included in a release version of dcmtk, this
  38. // class can be removed and classes that inherit from it
  39. // can inherit directly from DcmSCU instead.
  40. //
  41. //
  42. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  43. //
  44. #ifndef ctkDcmSCU_H
  45. #define ctkDcmSCU_H
  46. #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
  47. #include "dcmtk/dcmdata/dctk.h" /* Covers most common dcmdata classes */
  48. #include "dcmtk/dcmnet/dcompat.h"
  49. #include "dcmtk/dcmnet/dimse.h" /* DIMSE network layer */
  50. #include "dcmtk/dcmnet/dcasccff.h" /* For reading a association config file */
  51. #include "dcmtk/dcmnet/dcasccfg.h" /* For holding association cfg file infos */
  52. #include "dcmtk/ofstd/oflist.h"
  53. #include "ctkDICOMCoreExport.h"
  54. //
  55. // CTK: these return conditions copied from cond.cc
  56. //
  57. const OFConditionConst NET_ECC_AlreadyConnected (OFM_dcmnet, 1010, OF_error, "Already connected");
  58. const OFConditionConst NET_ECC_NoPresentationContextsDefined (OFM_dcmnet, 1005, OF_error, "No Presentation Contexts defined");
  59. const OFConditionConst NET_ECC_NoAcceptablePresentationContexts(OFM_dcmnet, 1006, OF_error, "No acceptable Presentation Contexts");
  60. const OFConditionConst NET_ECC_InvalidSOPClassUID (OFM_dcmnet, 1000, OF_error, "Invalid SOP Class UID");
  61. const OFConditionConst NET_ECC_InvalidSOPInstanceUID (OFM_dcmnet, 1002, OF_error, "Invalid SOP Instance UID");
  62. const OFConditionConst NET_ECC_UnknownStorageSOPClass (OFM_dcmnet, 1001, OF_error, "Unknown Storage SOP Class");
  63. const OFConditionConst NET_ECC_UnknownTransferSyntax (OFM_dcmnet, 1004, OF_error, "Unknown Transfer Syntax");
  64. const OFCondition NET_EC_AlreadyConnected (NET_ECC_AlreadyConnected);
  65. const OFCondition NET_EC_NoPresentationContextsDefined (NET_ECC_NoPresentationContextsDefined);
  66. const OFCondition NET_EC_NoAcceptablePresentationContexts(NET_ECC_NoAcceptablePresentationContexts);
  67. const OFCondition NET_EC_InvalidSOPClassUID (NET_ECC_InvalidSOPClassUID);
  68. const OFCondition NET_EC_UnknownStorageSOPClass (NET_ECC_UnknownStorageSOPClass);
  69. const OFCondition NET_EC_InvalidSOPInstanceUID (NET_ECC_InvalidSOPInstanceUID);
  70. const OFCondition NET_EC_UnknownTransferSyntax (NET_ECC_UnknownTransferSyntax);
  71. /** Different types of closing an association
  72. */
  73. enum DcmCloseAssociationType
  74. {
  75. /// Release the current association
  76. DCMSCU_RELEASE_ASSOCIATION,
  77. /// Abort the current association
  78. DCMSCU_ABORT_ASSOCIATION,
  79. /// Peer requested release (Aborting)
  80. DCMSCU_PEER_REQUESTED_RELEASE,
  81. /// Peer aborted the association
  82. DCMSCU_PEER_ABORTED_ASSOCIATION
  83. };
  84. /** Storage mode used for DICOM objects received via C-STORE
  85. */
  86. enum DcmStorageMode
  87. {
  88. /// Ignore any objects received via C-STORE
  89. DCMSCU_STORAGE_IGNORE,
  90. /// Try to store the objects to disk
  91. DCMSCU_STORAGE_DISK,
  92. /// Try to store to disk in bit-preserving mode. This is especially useful
  93. /// for huge files that cannot fully be received in memory since the
  94. /// data is directly streamed to disk. Originally, this was introduced for
  95. /// DICOM signatures which can be kept valid this way.
  96. DCMSCU_STORAGE_BIT_PRESERVING
  97. };
  98. /** Base class for C-FIND, C-MOVE and C-GET responses
  99. */
  100. class CTK_DICOM_CORE_EXPORT QRResponse
  101. {
  102. public:
  103. /** Standard constructor.
  104. */
  105. QRResponse() :
  106. m_messageIDRespondedTo(0),
  107. m_affectedSOPClassUID(),
  108. m_dataset(NULL),
  109. m_status(0),
  110. m_statusDetail(NULL) {}
  111. /** Destructor, cleans up internal memory (dataset if present).
  112. */
  113. virtual ~QRResponse() { delete m_dataset; delete m_statusDetail; }
  114. /// The message ID responded to (mandatory response field,
  115. /// equals message ID from request)
  116. Uint16 m_messageIDRespondedTo;
  117. /// Optional response field according to part 7 of the standard
  118. /// If present, equals SOP Class UID from request.
  119. OFString m_affectedSOPClassUID;
  120. /// Conditional response field (NULL if absent). From the standard (2009,
  121. /// part 4, C.4.2.1.4.2), for C-MOVE: In Q/R if no C-STORE sub-operation
  122. /// failed, Failed SOP Instance UID List (0008,0058) is absent and
  123. /// therefore no Data Set shall be sent in the C-MOVE response. Further
  124. /// rules: Statuses of Canceled, Failure, Refused, or Warning shall
  125. /// contain the Failed SOP Instance UID List Attribute; status of
  126. /// Pending shall not.
  127. DcmDataset *m_dataset;
  128. /// The returned DIMSE status (mandatory Response Field)
  129. Uint16 m_status;
  130. /// Status detail (NULL if absent). For some DIMSE return status codes,
  131. /// an additional dataset is sent which gives further information (i.e.
  132. /// in case of warnings or errors).
  133. DcmDataset *m_statusDetail;
  134. private:
  135. /** Private undefined copy constructor.
  136. * @param other The find response to copy from
  137. */
  138. QRResponse(const QRResponse& other);
  139. /** Private undefined assignment operator.
  140. * @param other The find response that should be assigned from
  141. */
  142. QRResponse& operator=(const QRResponse& other);
  143. };
  144. /// Base class representing for single C-GET or C-MOVE response
  145. class CTK_DICOM_CORE_EXPORT RetrieveResponse : public QRResponse
  146. {
  147. public:
  148. /** Standard constructor
  149. */
  150. RetrieveResponse() :
  151. m_numberOfRemainingSubops(0),
  152. m_numberOfCompletedSubops(0),
  153. m_numberOfFailedSubops(0),
  154. m_numberOfWarningSubops(0) {}
  155. /** Destructor, cleans up internal memory
  156. */
  157. virtual ~RetrieveResponse() {}
  158. /** Prints response to INFO log level.
  159. */
  160. void print();
  161. /// Number of remaining sub operations (in Q/R: C-STORE calls).
  162. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  163. /// For others, the field may be filled.
  164. Uint16 m_numberOfRemainingSubops;
  165. /// Number of successfully completed sub operations (in Q/R: C-STORE calls).
  166. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  167. /// For others, the field may be filled.
  168. Uint16 m_numberOfCompletedSubops;
  169. /// Number of failed sub operations (in Q/R: C-STORE calls).
  170. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  171. /// For others, the field may be filled.
  172. Uint16 m_numberOfFailedSubops;
  173. /// Number generated warnings generated by sub operations (in Q/R: C-STORE calls).
  174. /// For Q/R MOVE and GET, for status of pending this field shall be filled.
  175. /// For others, the field may be filled.
  176. Uint16 m_numberOfWarningSubops;
  177. private:
  178. /** Private undefined copy constructor
  179. * @param other Response to copy from
  180. */
  181. RetrieveResponse(const RetrieveResponse& other);
  182. /** Private undefined assignment operator
  183. * @param other Response that should be assigned from
  184. */
  185. RetrieveResponse& operator=(const RetrieveResponse& other);
  186. };
  187. /** Base class for implementing DICOM Service Class User functionality. The class offers
  188. * support for negotiating associations and sending and receiving arbitrary DIMSE messages
  189. * on that connection. DcmSCU has built-in C-ECHO support so derived classes do not have to
  190. * implement that capability on their own.
  191. * @warning This class is EXPERIMENTAL. Be careful to use it in production environment.
  192. * @warning This is a copy of the DcmSCU class - see not at top of file
  193. */
  194. class CTK_DICOM_CORE_EXPORT ctkDcmSCU
  195. {
  196. public:
  197. /** Constructor, just initializes internal class members
  198. */
  199. ctkDcmSCU();
  200. /** Virtual destructor
  201. */
  202. virtual ~ctkDcmSCU();
  203. /** Add presentation context to be used for association negotiation
  204. * @param abstractSyntax [in] Abstract syntax name in UID format
  205. * @param xferSyntaxes [in] List of transfer syntaxes to be added for the given abstract
  206. * syntax
  207. * @param role [in] The role to be negotiated
  208. * @return EC_Normal if adding was successful, otherwise error code
  209. */
  210. OFCondition addPresentationContext(const OFString &abstractSyntax,
  211. const OFList<OFString> &xferSyntaxes,
  212. const T_ASC_SC_ROLE role = ASC_SC_ROLE_DEFAULT);
  213. /** Initialize network, i.e.\ prepare for association negotiation. If the SCU is already
  214. * connected, the call will not be successful and the old connection keeps open.
  215. * @return EC_Normal if initialization was successful, otherwise error code.
  216. * NET_EC_AlreadyConnected if SCU is already connected.
  217. */
  218. virtual OFCondition initNetwork();
  219. /** Negotiate association by using presentation contexts and parameters as defined by
  220. * earlier function calls. If negotiation fails, there is no need to close the association
  221. * or to do anything else with this class.
  222. * @return EC_Normal if negotiation was successful, otherwise error code.
  223. * NET_EC_AlreadyConnected if SCU is already connected.
  224. */
  225. virtual OFCondition negotiateAssociation();
  226. /** After negotiation association, this call returns the first usable presentation context
  227. * given the desired abstract syntax and transfer syntax
  228. * @param abstractSyntax [in] The abstract syntax (UID) to look for
  229. * @param transferSyntax [in] The transfer syntax (UID) to look for. If empty, the transfer
  230. * syntax is not checked.
  231. * @return Adequate Presentation context ID that can be used. 0 if none found.
  232. */
  233. T_ASC_PresentationContextID findPresentationContextID(const OFString &abstractSyntax,
  234. const OFString &transferSyntax);
  235. /** After a successful association negotiation, this function is called to return the
  236. * presentation context ID that best matches the desired abstract syntax and transfer
  237. * syntax (TS). The function tries to do the following:
  238. * - If possible finds a presentation context with matching TS
  239. * - Else then tries to find an explicit VR uncompressed TS presentation context
  240. * - Else then tries to find an implicit VR uncompressed TS presentation context
  241. * - Else finally accepts each matching presentation ctx independent of TS.
  242. * @param abstractSyntax [in] The abstract syntax (UID) to look for
  243. * @param transferSyntax [in] The transfer syntax (UID) to look for. If empty, the transfer
  244. * syntax is not checked.
  245. * @return Adequate Presentation context ID that can be used. 0 if no appropriate
  246. * presentation context could be found at all.
  247. */
  248. T_ASC_PresentationContextID findAnyPresentationContextID(const OFString &abstractSyntax,
  249. const OFString &transferSyntax);
  250. /** This function sends a C-ECHO command via network to another DICOM application
  251. * @param presID [in] Presentation context ID to use. A value of 0 lets SCP class tries
  252. * to choose one on its own.
  253. * @return EC_Normal if echo was successful, an error code otherwise
  254. *
  255. */
  256. virtual OFCondition sendECHORequest(const T_ASC_PresentationContextID presID);
  257. /** This function sends a C-STORE request on the currently opened association and receives
  258. * the corresponding response then. If required and supported, the dataset of the SOP
  259. * instance can be converted automatically to the network transfer syntax that was
  260. * negotiated (and is specified by the parameter 'presID'). However, this feature is
  261. * disabled by default. See setDatasetConversionMode() on how to enable it.
  262. * @param presID [in] Contains in the end the ID of the presentation context which
  263. * was specified in the DIMSE command. If 0 is given, the
  264. * function tries to find an approriate presentation context
  265. * itself (based on SOP class and original transfer syntax of
  266. * the 'dicomFile' or 'dataset').
  267. * @param dicomFile [in] The filename of the DICOM file to be sent. Alternatively, a
  268. * dataset can be given in the next parameter. If both are given
  269. * the dataset from the file name is used.
  270. * @param dataset [in] The dataset to be sent. Alternatively, a filename can be
  271. * specified in the previous parameter. If both are given the
  272. * dataset from the filename is used.
  273. * @param rspStatusCode [out] The response status code received. 0 means success, others
  274. * can be found in the DICOM standard.
  275. * @return EC_Normal if request could be issued and response was received successfully,
  276. * error code otherwise. That means that if the receiver sends a response denoting
  277. * failure of the storage request, EC_Normal will be returned.
  278. */
  279. virtual OFCondition sendSTORERequest(const T_ASC_PresentationContextID presID,
  280. const OFString &dicomFile,
  281. DcmDataset *dataset,
  282. Uint16 &rspStatusCode);
  283. /** Sends a C-MOVE Request on given presentation context and receives list of responses.
  284. * The function receives the first response and then calls the function handleMOVEResponse()
  285. * which gets the relevant presentation context together with the response dataset and
  286. * status information. Then it waits again for the next response, if there are more to
  287. * come (i.e. response status is PENDING). In the end, after receiving all responses, the
  288. * full list of responses is returned to the caller. If he is not interested, he just sets
  289. * responses=NULL when calling the function.
  290. * This function can be overwritten by actual SCU implementations but just should work fine
  291. * for most people.
  292. * @param presID [in] The presentation context ID that should be used. Must be an odd
  293. * number.
  294. * @param moveDestinationAETitle [in] The move destination's AE title, i.e.\ the one that
  295. * is used for connection to the storage server.
  296. * @param dataset [in] The dataset containing the information about the object(s) to
  297. * be retrieved
  298. * @param responses [out] The incoming C-MOVE responses for this request. The caller is
  299. * responsible for providing a non-NULL pointer for this case.
  300. * After receiving the results, the caller is responsible for
  301. * freeing the memory of this variable. If NULL is specified, the
  302. * responses will not bereturned to the caller.
  303. * @return EC_Normal if everything went fine, i.e.\ if request could be send and responses
  304. * (with whatever status) could be received.
  305. */
  306. virtual OFCondition sendMOVERequest(const T_ASC_PresentationContextID presID,
  307. const OFString &moveDestinationAETitle,
  308. DcmDataset *dataset,
  309. OFList<RetrieveResponse*> *responses);
  310. /** This is the standard handler for C-MOVE message responses: It just adds up all responses
  311. * it receives and prints a DEBUG message. Therefore, it is called for each response
  312. * received in sendMOVERequest(). The idea is of course to overwrite this function in a
  313. * derived, actual SCU implementation if required. Thus, after each response, the caller of
  314. * sendMOVERequest() can decide on its own whether he wants to cancel the C-MOVE session,
  315. * terminate the association, do something useful or whatever. Thus this function is a more
  316. * object-oriented kind of callback.
  317. * @param presID [in] The presentation context ID where the response was received on.
  318. * @param response [in] The C-MOVE response received.
  319. * @param waitForNextResponse [out] Denotes whether SCU should try to receive another
  320. * response. If set to OFTrue, then sendMOVERequest() will
  321. * continue waiting for responses. The current
  322. * implementation does that for all responses do not have
  323. * status Failed, Warning, Success or unknown. If set to
  324. * OFFalse, sendMOVERequest() will return control to the
  325. * caller.
  326. * @return EC_Normal, if response could be handled. Error code otherwise.
  327. * The current implementation always returns EC_Normal.
  328. */
  329. virtual OFCondition handleMOVEResponse(const T_ASC_PresentationContextID presID,
  330. RetrieveResponse *response,
  331. OFBool &waitForNextResponse);
  332. /** Sends a C-GET Request on given presentation context and receives list of responses. It
  333. * then switches control to the function handleCGETSession().
  334. * The full list of responses is returned to the caller. If he is not interested, he can
  335. * set responses=NULL when calling the function.
  336. * This function can be overwritten by actual SCU implementations but just should work fine
  337. * for most people.
  338. * @param presID [in] The presentation context ID that should be used. Must be an odd
  339. * number.
  340. * @param dataset [in] The dataset containing the information about the
  341. * object(s) to be retrieved
  342. * @param responses [out] The incoming C-GET responses for this request. If the caller
  343. * specifies NULL, no responses will be returned; otherwise there
  344. * should be at least one final C-GET response (mandatory). C-GET
  345. * responses after each DICOM object received are optional and may
  346. * have been ommitted by the server.
  347. * @return EC_Normal if everything went fine, i.e.\ if request could be sent and expected
  348. * responses (with whatever status) could be received.
  349. */
  350. virtual OFCondition sendCGETRequest(const T_ASC_PresentationContextID presID,
  351. DcmDataset *dataset,
  352. OFList<RetrieveResponse*> *responses);
  353. /** Does the logic for switching between C-GET Response and C-STORE Requests. Sends a C-GET
  354. * Request on given presentation context and receives list of responses. Ihe full list of
  355. * responses is returned to the caller. If he is not interested, he can set responses=NULL
  356. * when calling the function. After sending a C-GET Request, there might be two different
  357. * responses coming in: C-GET-RSP (optional after each received object and mandatory after
  358. * the last object) or a mandatory C-STORE for each incoming object that is received due to
  359. * the request. This function therefore either calls handleCGETResponse() or
  360. * handleSTORERequest() in order to deal with the incoming message. All other messages lead
  361. * to an error within this handler.
  362. * This function can be overwritten by actual SCU implementations but just should work fine
  363. * for most people.
  364. * @param presID [in] The presentation context ID that should be used. Must be an odd
  365. * number.
  366. * @param dataset [in] The dataset containing the information about the object(s) to be
  367. * retrieved
  368. * @param responses [out] The incoming C-GET responses for this request. If the caller
  369. * specifies NULL, no responses will be returned; otherwise there
  370. * should be at least one final C-GET response (mandatory). C-GET
  371. * responses after each DICOM object received are optional and may
  372. * have been ommitted by the server.
  373. * @return EC_Normal if everything went fine, i.e.\ if request could be send
  374. * and expected responses (with whatever status) could be received.
  375. */
  376. virtual OFCondition handleCGETSession(const T_ASC_PresentationContextID presID,
  377. DcmDataset *dataset,
  378. OFList<RetrieveResponse*> *responses);
  379. /** Function handling a single C-GET Response. This standard handler reads the status of the
  380. * response and decides whether to receive any further messages related to the original
  381. * C-GET Request or whether the last response was received or an error occured.
  382. * @param presID [in] The presentation context the C-GET Response was
  383. * received on.
  384. * @param response [in] The response received
  385. * @param continueCGETSession [out] Defines whether it is decided to wait for further C-GET
  386. * Responses/C-STORE Requests within this C-GET session
  387. * @return If no errors occur (dataset response NULL, SCU not connected), this method will
  388. * return EC_Normal, otherwise error code.
  389. */
  390. virtual OFCondition handleCGETResponse(const T_ASC_PresentationContextID presID,
  391. RetrieveResponse* response,
  392. OFBool& continueCGETSession);
  393. /** Function handling a single C-STORE Request. If storage mode is set to disk (default),
  394. * this function is called and the incoming object stored to disk.
  395. * @param presID [in] The presentation context the C-STORE Response was
  396. * received on.
  397. * @param incomingObject [in] The dataset (the object) received
  398. * @param continueCGETSession [out] Defines whether it is decided to wait for further
  399. * C-GET Responses/C-STORE requests within this C-GET
  400. * session.
  401. * @param cStoreReturnStatus [out] Denotes the desired C-STORE return status.
  402. * @return If errors occur (incomingObject NULL or SCU not connected or file could not be
  403. * stored), this method will return an error code otherwise EC_Normal.
  404. */
  405. virtual OFCondition handleSTORERequest(const T_ASC_PresentationContextID presID,
  406. DcmDataset *incomingObject,
  407. OFBool& continueCGETSession,
  408. Uint16& cStoreReturnStatus);
  409. /** Function handling a single C-STORE Request. If storage mode is set to bit preserving,
  410. * this function is called and the incoming object stored directly to disk, i.e. not stored
  411. * fully in memory.
  412. * @param presID [in] The presentation context the C-STORE Response was received
  413. * on.
  414. * @param filename [in] The filename to store to
  415. * @param request [in] The incoming C-STORE request command set
  416. * @param callback [in] The desired user callback
  417. * @param callbackContext [in] The desired user callback data
  418. * @return If errors occur (incomingObject NULL or SCU not connected filename not
  419. * specified), this method will return an error code otherwise EC_Normal.
  420. */
  421. virtual OFCondition handleSTORERequestFile(T_ASC_PresentationContextID *presID,
  422. const OFString& filename,
  423. T_DIMSE_C_StoreRQ* request,
  424. DIMSE_ProgressCallback callback,
  425. void *callbackContext);
  426. /** This function is called if an object was receveid due to a C-GET request and can be
  427. * overwritten by a user in order to be informed about such an event. The standard handles
  428. * just prints a message. Note that this function is not called if the SCU is in storage
  429. * mode DCMSCU_STORAGE_IGNORE.
  430. * @param filename [in] The filename written
  431. * @param sopClassUID [in] The SOP Class UID of the object written
  432. * @param sopInstanceUID [in] The SOP Instance UID of the object written
  433. */
  434. virtual void notifyInstanceStored(const OFString& filename,
  435. const OFString& sopClassUID,
  436. const OFString& sopInstanceUID) const;
  437. /** Sends a C-FIND Request on given presentation context and receives list of responses.
  438. * The function receives the first response and then calls the function handleFINDResponse
  439. * which gets the relevant presentation context together with the response dataset and
  440. * status information. Then it waits again for the next response, if there are more to
  441. * come (i.e. response status is PENDING). In the end, after receiving all responses, the
  442. * full list of responses is returned to the caller. If he is not interested, he just sets
  443. * responses=NULL when calling the function.
  444. * This function can be overwritten by actual SCU implementations but just should work fine
  445. * for most people.
  446. * @param presID [in] The presentation context ID that should be used. Must be an odd
  447. * number.
  448. * @param queryKeys [in] The dataset containing the query keys to be searched for on the
  449. * server (SCP).
  450. * @param responses [out] The incoming C-FIND responses for this request. The caller is
  451. * responsible for providing a non-NULL pointer for this case.
  452. * After receiving the results, the caller is responsible for
  453. * freeing the memory of this variable. If NULL is specified, the
  454. * responses will be not returned to the caller.
  455. * @return EC_Normal if everything went fine, i.e.\ if request could be send and responses
  456. * (with whatever status) could be received.
  457. */
  458. virtual OFCondition sendFINDRequest(const T_ASC_PresentationContextID presID,
  459. DcmDataset *queryKeys,
  460. OFList<QRResponse*> *responses);
  461. /** This is the standard handler for C-FIND message responses: It just adds up all responses
  462. * it receives and prints a DEBUG message. Therefore, it is called for each response
  463. * received in sendFINDRequest(). The idea is of course to overwrite this function in a
  464. * derived, actual SCU implementation if required. Thus, after each response, the caller of
  465. * sendFINDRequest() can decide on its own whether he wants to cancel the C-FIND session,
  466. * terminate the association, do something useful or whatever. That way this is a more
  467. * object-oriented kind of callback.
  468. * @param presID [in] The presentation context ID where the response was received on.
  469. * @param response [in] The C-FIND response received.
  470. * @param waitForNextResponse [out] Denotes whether SCU should try to receive another
  471. * response. If set to OFTrue, then sendFINDRequest()
  472. * will continue waiting for responses. The current
  473. * implementation does that for all responses do not have
  474. * status SUCESSS. If set to OFFalse, sendFINDRequest()
  475. * will return control to the caller.
  476. * @return EC_Normal, if response could be handled. Error code otherwise.
  477. * The current implementation always returns EC_Normal.
  478. */
  479. virtual OFCondition handleFINDResponse(const T_ASC_PresentationContextID presID,
  480. QRResponse *response,
  481. OFBool &waitForNextResponse);
  482. /** Send C-CANCEL and, therefore, ends the C-FIND -GET or -MOVE session, i.e.\ no further
  483. * responses will be handled. A call to this function only makes sense if an association
  484. * is open, the given presentation context represents a valid C-FIND/GET/MOVE-enabled SOP
  485. * class and usually only, if the last command send on that presentation context was a
  486. * C-FIND message.
  487. * @param presID [in] The presentation context ID where the C-CANCEL should be sent on.
  488. * @return The current implementation always returns EC_Normal.
  489. */
  490. virtual OFCondition sendCANCELRequest(const T_ASC_PresentationContextID presID);
  491. /** This function sends a N-ACTION request on the currently opened association and receives
  492. * the corresponding response then
  493. * @param presID [in] The ID of the presentation context to be used for sending
  494. * the request message. Should not be 0.
  495. * @param sopInstanceUID [in] The requested SOP Instance UID
  496. * @param actionTypeID [in] The action type ID to be used
  497. * @param reqDataset [in] The dataset to be sent
  498. * @param rspStatusCode [out] The response status code received. 0 means success,
  499. * others can be found in the DICOM standard.
  500. * @return EC_Normal if request could be issued and response was received successfully,
  501. * an error code otherwise
  502. */
  503. virtual OFCondition sendACTIONRequest(const T_ASC_PresentationContextID presID,
  504. const OFString &sopInstanceUID,
  505. const Uint16 actionTypeID,
  506. DcmDataset *reqDataset,
  507. Uint16 &rspStatusCode);
  508. /** This function sends N-EVENT-REPORT request and receives the corresponding response
  509. * @param presID [in] The ID of the presentation context to be used for sending
  510. * the request message. Should not be 0.
  511. * @param sopInstanceUID [in] The requested SOP Instance UID
  512. * @param eventTypeID [in] The event type ID to be used
  513. * @param reqDataset [in] The request dataset to be sent
  514. * @param rspStatusCode [out] The response status code received. 0 means success,
  515. * others can be found in the DICOM standard.
  516. * @return EC_Normal if request could be issued and response was received successfully,
  517. * an error code otherwise
  518. */
  519. virtual OFCondition sendEVENTREPORTRequest(const T_ASC_PresentationContextID presID,
  520. const OFString &sopInstanceUID,
  521. const Uint16 eventTypeID,
  522. DcmDataset *reqDataset,
  523. Uint16 &rspStatusCode);
  524. /** Receives N-EVENT-REPORT request on the currently opened association and sends a
  525. * corresponding response. Calls checkEVENTREPORTRequest() in order to determine the
  526. * DIMSE status code to be used for the N-EVENT-REPORT response.
  527. * @param reqDataset [out] Pointer to the dataset received
  528. * @param eventTypeID [out] Event Type ID from the command set received
  529. * @param timeout [in] Optional timeout in seconds for receiving data. This value
  530. * (if not 0) overwrites the standard DIMSE timeout and also
  531. * enables the non-blocking mode for receiving the request.
  532. * @return status, EC_Normal if successful, an error code otherwise
  533. */
  534. virtual OFCondition handleEVENTREPORTRequest(DcmDataset *&reqDataset,
  535. Uint16 &eventTypeID,
  536. const int timeout = 0);
  537. /** Closes the association created by this SCU. Also resets the current association.
  538. * @param closeType [in] Define whether to release or abort the association
  539. */
  540. virtual void closeAssociation(const DcmCloseAssociationType closeType);
  541. /* Set methods */
  542. /** Set maximum PDU length (to be received by SCU)
  543. * @param maxRecPDU [in] The maximum PDU size to use in bytes
  544. */
  545. void setMaxReceivePDULength(const unsigned long maxRecPDU);
  546. /** Set whether to send in DIMSE blocking or non-blocking mode
  547. * @param blockingMode [in] Either blocking or non-blocking mode
  548. */
  549. void setDIMSEBlockingMode(const T_DIMSE_BlockingMode blockingMode);
  550. /** Set SCU's AETitle to be used in association negotiation
  551. * @param myAETtitle [in] The SCU's AETitle to be used
  552. */
  553. void setAETitle(const OFString &myAETtitle);
  554. /** Set SCP's host (hostname or IP address) to talk to in association negotiation
  555. * @param peerHostName [in] The SCP's hostname or IP address to be used
  556. */
  557. void setPeerHostName(const OFString &peerHostName);
  558. /** Set SCP's AETitle to talk to in association negotiation
  559. * @param peerAETitle [in] The SCP's AETitle to be used
  560. */
  561. void setPeerAETitle(const OFString &peerAETitle);
  562. /** Set SCP's port number to connect to for association negotiation
  563. * @param peerPort [in] The SCP's port number
  564. */
  565. void setPeerPort(const Uint16 peerPort);
  566. /** Set timeout for receiving DIMSE messages
  567. * @param dimseTimeout [in] DIMSE Timeout in seconds for receiving data. If the blocking
  568. * mode is DIMSE_NONBLOCKING and we are trying to read data from
  569. * the incoming socket stream and no data has been received.
  570. */
  571. void setDIMSETimeout(const Uint32 dimseTimeout);
  572. /** Set timeout for receiving ACSE messages
  573. * @param acseTimeout [in] ACSE Timeout in seconds used by timer for message timeouts
  574. * during association negotiation
  575. */
  576. void setACSETimeout(const Uint32 acseTimeout);
  577. /** Set an association configuration file and profile to be used
  578. * @param filename [in] File name of the association configuration file
  579. * @param profile [in] Profile inside the association negotiation file
  580. */
  581. void setAssocConfigFileAndProfile(const OFString &filename,
  582. const OFString &profile);
  583. /** Set the directory that should be used by the standard C-GET handler to store objects
  584. * that come in with the corresponding C-STORE rqeuests
  585. * @param storeDir [in] The directory to store to. It is checked in handleSTORERequest()
  586. * whether the directory is writeable and readable. Per default, the
  587. * received objects are stored in the current working directory.
  588. */
  589. void setStorageDir(const OFString& storeDir);
  590. /** Set the storage mode to be used. Default is DCMSCU_STORAGE_DISK.
  591. * @param storageMode The storage mode to be used.
  592. */
  593. void setStorageMode(const DcmStorageMode storageMode);
  594. /** Set whether to show presentation contexts in verbose or debug mode
  595. * @param mode [in] Show presentation contexts in verbose mode if OFTrue. By default, the
  596. * presentation contexts are shown in debug mode.
  597. */
  598. void setVerbosePCMode(const OFBool mode);
  599. /** Set the mode that specifies whether the transfer syntax of the dataset can be changed
  600. * for network transmission. This mainly covers the compression/decompression of datasets,
  601. * which is disabled by default.
  602. * @param mode [in] Allow dataset conversion if OFTrue
  603. */
  604. void setDatasetConversionMode(const OFBool mode);
  605. /* Get methods */
  606. /** Get current connection status
  607. * @return OFTrue if SCU is currently connected, OFFalse otherwise
  608. */
  609. OFBool isConnected() const;
  610. /** Returns maximum PDU length configured to be received by SCU
  611. * @return Maximum PDU length in bytes
  612. */
  613. Uint32 getMaxReceivePDULength() const;
  614. /** Returns whether DIMSE messaging is configured to be blocking or unblocking
  615. * @return The blocking mode configured
  616. */
  617. T_DIMSE_BlockingMode getDIMSEBlockingMode() const;
  618. /** Returns the SCU's own configured AETitle
  619. * @return The AETitle configured for this SCU
  620. */
  621. const OFString &getAETitle() const;
  622. /** Returns the SCP's (peer's) host name configured
  623. * @return The hostname (or IP) configured to be talked to
  624. */
  625. const OFString &getPeerHostName() const;
  626. /** Returns the SCP's (peer's) AETitle configured
  627. * @return The AETitle configured to be talked to
  628. */
  629. const OFString &getPeerAETitle() const;
  630. /** Returns the SCP's (peer's) TCP/IP port configured
  631. * @return The port configured to talked to
  632. */
  633. Uint16 getPeerPort() const;
  634. /** Returns the DIMSE timeout configured defining how long SCU will wait for DIMSE responses
  635. * @return The DIMSE timeout configured
  636. */
  637. Uint32 getDIMSETimeout() const;
  638. /** Returns the timeout configured defining how long SCU will wait for messages during ACSE
  639. * messaging (association negotiation)
  640. * @return The ACSE timeout configured
  641. */
  642. Uint32 getACSETimeout() const;
  643. /** Returns the verbose presentation context mode configured specifying whether details on
  644. * the presentation contexts (negotiated during association setup) should be shown in
  645. * verbose or debug mode. The latter is the default.
  646. * @return The verbose presentation context mode configured
  647. */
  648. OFBool getVerbosePCMode() const;
  649. /** Returns the mode that specifies whether the transfer syntax of the dataset can be
  650. * changed for network transmission. This mainly covers the compression/decompression
  651. * of datasets, which is disabled by default.
  652. * @return The transfer syntax conversion mode
  653. */
  654. OFBool getDatasetConversionMode() const;
  655. /** Returns the storage directory used for storing objects received with C-STORE requests
  656. * in the context of C-GET sessions. Default is empty string which refers to the current
  657. * working directory.
  658. * @return The storage directory
  659. */
  660. OFString getStorageDir() const;
  661. /** Returns the storage mode enabled
  662. * @return The storage mode enabled
  663. */
  664. DcmStorageMode getStorageMode() const;
  665. /** Returns whether SCU is configured to create a TLS connection with the SCP
  666. * @return OFFalse for this class but may be overriden by derived classes
  667. */
  668. OFBool getTLSEnabled() const;
  669. /** Deletes internal networking structures from memory */
  670. void freeNetwork();
  671. protected:
  672. /** Sends a DIMSE command and possibly also a dataset from a data object via network to
  673. * another DICOM application
  674. * @param presID [in] Presentation context ID to be used for message
  675. * @param msg [in] Structure that represents a certain DIMSE command which
  676. * shall be sent
  677. * @param dataObject [in] The instance data which shall be sent to the other DICOM
  678. * application; NULL, if there is none
  679. * @param callback [in] Pointer to a function which shall be called to indicate
  680. * progress
  681. * @param callbackContext [in] Pointer to data which shall be passed to the progress
  682. * indicating function
  683. * @param commandSet [out] If this parameter is not NULL it will return a copy of the
  684. * DIMSE command which is sent to the other DICOM application
  685. * @return EC_Normal if sending request was successful, an error code otherwise
  686. */
  687. OFCondition sendDIMSEMessage(const T_ASC_PresentationContextID presID,
  688. T_DIMSE_Message *msg,
  689. DcmDataset *dataObject,
  690. DIMSE_ProgressCallback callback,
  691. void *callbackContext,
  692. DcmDataset **commandSet = NULL);
  693. /** Returns SOP Class UID, SOP Instance UID and original transfer syntax for a given dataset.
  694. * If the dataset is NULL, all returned values will be undefined (i.e. empty or EXS_Unknown).
  695. * @param dataset [in] The dataset to read from
  696. * @param sopClassUID [out] The value of attribute SOP Class UID if present
  697. * @param sopInstanceUID [out] The value of attribute SOP Instance UID if present
  698. * @param transferSyntax [out] The value of transfer syntax that originally was read from
  699. * disk. Will be unknown if the dataset was created in memory.
  700. * @return EC_Normal if all information could be retrieved and is valid, an error code
  701. * otherwise
  702. */
  703. OFCondition getDatasetInfo(DcmDataset *dataset,
  704. OFString &sopClassUID,
  705. OFString &sopInstanceUID,
  706. E_TransferSyntax &transferSyntax);
  707. /** Tells DcmSCU to use a secure TLS connection described by the given TLS layer
  708. * @param tlayer [in] The TLS transport layer including all TLS parameters
  709. * @return EC_Normal if given transport layer is ok, an error code otherwise
  710. */
  711. OFCondition useSecureConnection(DcmTransportLayer *tlayer);
  712. /** Receive DIMSE command (excluding dataset!) over the currently open association
  713. * @param presID [out] Contains in the end the ID of the presentation context
  714. * which was specified in the DIMSE command received
  715. * @param msg [out] The message received
  716. * @param statusDetail [out] If a non-NULL value is passed this variable will in the end
  717. * contain detailed information with regard to the status
  718. * information which is captured in the status element
  719. * (0000,0900). Note that the value for element (0000,0900) is
  720. * not contained in this return value but in internal msg. For
  721. * details on the structure of this object, see DICOM standard
  722. * part 7, annex C).
  723. * @param commandSet [out] If this parameter is not NULL, it will return a copy of the
  724. * DIMSE command which was received from the other DICOM
  725. * application. The caller is responsible to de-allocate the
  726. * returned object!
  727. * @param timeout [in] If this parameter is not 0, it specifies the timeout (in
  728. * seconds) to be used for receiving the DIMSE command.
  729. * Otherwise, the default timeout value is used (see
  730. * setDIMSETimeout()).
  731. * @return EC_Normal if command could be received successfully, an error code otherwise
  732. */
  733. OFCondition receiveDIMSECommand(T_ASC_PresentationContextID *presID,
  734. T_DIMSE_Message *msg,
  735. DcmDataset **statusDetail,
  736. DcmDataset **commandSet = NULL,
  737. const Uint32 timeout = 0);
  738. /** Receives one dataset (of instance data) via network from another DICOM application
  739. * @param presID [out] Contains in the end the ID of the presentation context
  740. * which was used in the PDVs that were received on the
  741. * network. If the PDVs show different presentation context
  742. * IDs, this function will return an error.
  743. * @param dataObject [out] Contains in the end the information which was received
  744. * over the network
  745. * @param callback [in] Pointer to a function which shall be called to indicate
  746. * progress
  747. * @param callbackContext [in] Pointer to data which shall be passed to the progress
  748. * indicating function
  749. * @return EC_Normal if dataset could be received successfully, an error code otherwise
  750. */
  751. OFCondition receiveDIMSEDataset(T_ASC_PresentationContextID *presID,
  752. DcmDataset **dataObject,
  753. DIMSE_ProgressCallback callback,
  754. void *callbackContext);
  755. /** clear list of presentation contexts. In addition, any currently selected association
  756. * configuration file is disabled.
  757. */
  758. void clearPresentationContexts();
  759. /** After negotiation association, this call returns the presentation context belonging
  760. * to the given presentation context ID
  761. * @param presID [in] The presentation context ID to look for
  762. * @param abstractSyntax [out] The abstract syntax (UID) for that ID.
  763. * Empty, if such a presentation context does not exist.
  764. * @param transferSyntax [out] The transfer syntax (UID) for that ID.
  765. * Empty, if such a presentation context does not exist.
  766. */
  767. void findPresentationContext(const T_ASC_PresentationContextID presID,
  768. OFString &abstractSyntax,
  769. OFString &transferSyntax);
  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. private:
  812. /** Private undefined copy-constructor. Shall never be called.
  813. * @param src Source object
  814. */
  815. ctkDcmSCU(const ctkDcmSCU &src);
  816. /** Private undefined operator=. Shall never be called.
  817. * @param src Source object
  818. * @return Reference to this
  819. */
  820. ctkDcmSCU &operator=(const ctkDcmSCU &src);
  821. /// Associaton of this SCU. This class only handles 1 association at a time.
  822. T_ASC_Association *m_assoc;
  823. /// The DICOM network the association is based on
  824. T_ASC_Network *m_net;
  825. /// Association parameters
  826. T_ASC_Parameters *m_params;
  827. /// Configuration file for presentation contexts (optional)
  828. OFString m_assocConfigFilename;
  829. /// Profile in configuration file that should be used (optional)
  830. OFString m_assocConfigProfile;
  831. /// Defines presentation context, consisting of one abstract syntax name
  832. /// and a list of transfer syntaxes for this abstract syntax
  833. struct DcmSCUPresContext {
  834. /** Default constructor
  835. */
  836. DcmSCUPresContext()
  837. : abstractSyntaxName()
  838. , transferSyntaxes()
  839. , roleSelect(ASC_SC_ROLE_DEFAULT)
  840. {
  841. }
  842. /// Abstract Syntax Name of Presentation Context
  843. OFString abstractSyntaxName;
  844. /// List of Transfer Syntaxes for Presentation Context
  845. OFList<OFString> transferSyntaxes;
  846. /// Role Selection
  847. T_ASC_SC_ROLE roleSelect;
  848. };
  849. /// List of presentation contexts that should be negotiated
  850. OFList<DcmSCUPresContext> m_presContexts;
  851. /// Configuration file containing association parameters
  852. OFString m_assocConfigFile;
  853. /// The last DIMSE successfully sent, unresponded DIMSE request
  854. T_DIMSE_Message *m_openDIMSERequest;
  855. /// Maximum PDU size
  856. Uint32 m_maxReceivePDULength;
  857. /// DIMSE blocking mode
  858. T_DIMSE_BlockingMode m_blockMode;
  859. /// AEtitle of this application
  860. OFString m_ourAETitle;
  861. /// Peer hostname
  862. OFString m_peer;
  863. /// AEtitle of remote application
  864. OFString m_peerAETitle;
  865. /// Port of remote application entity
  866. Uint16 m_peerPort;
  867. /// DIMSE timeout
  868. Uint32 m_dimseTimeout;
  869. /// ACSE timeout
  870. Uint32 m_acseTimeout;
  871. /// Verbose PC mode
  872. OFBool m_verbosePCMode;
  873. /// Dataset conversion mode
  874. OFBool m_datasetConversionMode;
  875. /// Storage directory for objects received with C-STORE due to a
  876. /// running C-GET session. Per default, the received objects
  877. /// are stored in the current working directory.
  878. OFString m_storageDir;
  879. /// Set whether bit preserving storage should be enabled, i.e.\ any objects
  880. /// retrieved via C-STORE should be written directly to disk without
  881. /// any data correction/re-computation (e.g.\ group length calculations,
  882. /// padding, etc.). This is especially interesting for retaining valid
  883. /// signatures, and also to receive huge files which cannot be fully received
  884. /// in memory. Default is OFFalse (no bit preserving) storage.
  885. DcmStorageMode m_storageMode;
  886. /** Returns next available message ID free to be used by SCU
  887. * @return Next free message ID
  888. */
  889. Uint16 nextMessageID();
  890. };
  891. #endif // ctkDcmSCU_H
  892. /*
  893. ** CVS Log
  894. ** $Log: scu.h,v $
  895. ** Revision 1.39 2011-10-10 14:01:29 uli
  896. ** Moved SCU-specific error condition to the correct place.
  897. **
  898. ** Revision 1.38 2011-10-04 08:58:14 joergr
  899. ** Added flag that allows for specifying whether to convert a dataset to be
  900. ** transferred to the network transfer syntax. Also removed unused parameters
  901. ** "rspCommandSet" and "rspStatusDetail" from method sendSTORERequest().
  902. **
  903. ** Revision 1.37 2011-09-28 16:28:20 joergr
  904. ** Added general support for transfer syntax conversions to sendSTORERequest().
  905. **
  906. ** Revision 1.36 2011-09-28 15:25:34 joergr
  907. ** Return a more appropriate error code in case the dataset to be sent is
  908. ** invalid. This also required to introduce a return value for getDatasetInfo().
  909. **
  910. ** Revision 1.35 2011-09-28 13:31:56 joergr
  911. ** Added method that allows for clearing the list of presentation contexts.
  912. **
  913. ** Revision 1.34 2011-09-22 13:49:03 joergr
  914. ** Fixed incorrect comment on return code of some sendXXXRequest() methods.
  915. **
  916. ** Revision 1.33 2011-09-06 16:11:06 ogazzar
  917. ** Fixed typos in a log commit message.
  918. **
  919. ** Revision 1.32 2011-09-06 12:57:36 ogazzar
  920. ** Added a function to send N-EVENT-REPORT request and receive a reponse.
  921. **
  922. ** Revision 1.31 2011-08-25 15:46:18 joergr
  923. ** Further cleanup of minor inconsistencies regarding documentation, parameter
  924. ** names, log output and handling of status details information.
  925. **
  926. ** Revision 1.30 2011-08-25 15:05:06 joergr
  927. ** Changed data structure for Q/R responses from OFVector to OFList. Also fixed
  928. ** some possible memory leaks and made the FIND/MOVE/GET code more consistent.
  929. **
  930. ** Revision 1.29 2011-08-25 13:46:28 joergr
  931. ** Fixed minor issues in the API documentation, parameter and method names.
  932. **
  933. ** Revision 1.28 2011-08-25 09:31:33 onken
  934. ** Added C-GET functionality to DcmSCU class and accompanying getscu
  935. ** commandline application.
  936. **
  937. ** Revision 1.27 2011-05-25 09:57:54 ogazzar
  938. ** Renamed a function name.
  939. **
  940. ** Revision 1.26 2011-05-25 09:30:12 ogazzar
  941. ** Added a function to look for a presentation context ID that best matches
  942. ** the abstract syntax and the transfer syntax.
  943. **
  944. ** Revision 1.25 2011-05-24 13:17:58 onken
  945. ** Added missing default initializiation of role flag in presentation context
  946. ** constructor.
  947. **
  948. ** Revision 1.24 2011-05-24 08:28:08 ogazzar
  949. ** Added support for role selection negotiation.
  950. **
  951. ** Revision 1.23 2011-05-19 17:20:09 onken
  952. ** Fixed some documentation.
  953. **
  954. ** Revision 1.22 2011-05-19 09:57:26 onken
  955. ** Fixed message ID field in C-CANCEL request (should be the one of last
  956. ** request). In case of error status codes in C-MOVE responses, the default
  957. ** behaviour is now to not wait for further responses. Fixed log output level
  958. ** to better fit the messages while receiveing C-MOVE responses. Minor
  959. ** code and comment cleanups. Renamed function parameter in sendMOVEREquest
  960. ** to better reflect the standard.
  961. **
  962. ** Revision 1.21 2011-05-17 14:43:55 onken
  963. ** Removed some windows line endings.
  964. **
  965. ** Revision 1.20 2011-05-17 14:34:32 onken
  966. ** Completed doxygen documentation of DcmSCU class. Fixed some minor formatting
  967. ** issues. Fixed CVS log at end of the file. Implemented C-CANCEL message.
  968. ** Fixed some minor formatting issues. Changed C-ECHO implementation to rely
  969. ** on sendDIMSEMesage as the other DIMSE functions do. Changed some public
  970. ** function arguments to const to be more correct. Fixed CVS log at the end
  971. ** of the file. Re-formatted CHANGES log entry from 2011-04-28.
  972. **
  973. ** Revision 1.19 2011-05-17 14:26:19 onken
  974. ** Implemented C-CANCEL message. Fixed some minor formatting issues.
  975. ** Changed C-ECHO implementation to rely on sendDIMSEMesage as the other
  976. ** DIMSE functions do. Changed some public function arguments to const to be
  977. ** more correct. Fixed CVS log at the end of the scu.cc file.
  978. **
  979. ** Revision 1.18 2011-04-28 17:50:05 onken
  980. ** Protected public networking functions for creating an association
  981. ** from being called twice. Enhanced protection of DIMSE messaging
  982. ** functions from being called without being connected. Introduced
  983. ** status detail into C-FIND responses (and C-MOVE responses). Was
  984. ** not accessible to the caller before. Minor code cleanups. Added
  985. ** C-MOVE code for retrieving DICOM objects. So far only retrieving
  986. ** on a separate connection is supported. Added function for cleaning
  987. ** up internal memory from destructor. This function also fixes a
  988. ** memory leak in case users call initNetwork more than one time.
  989. ** Added error code returned by functions if SCU is already connected.
  990. **
  991. ** Revision 1.17 2011-02-16 08:55:13 joergr
  992. ** Fixed issue in sendSTORERequest() when sending a dataset that was created
  993. ** in memory (and which has, therefore, an original transfer of EXS_Unknown).
  994. **
  995. ** Revision 1.16 2011-02-04 12:57:40 uli
  996. ** Made sure all members are initialized in the constructor (-Weffc++).
  997. **
  998. ** Revision 1.15 2011-02-04 11:24:40 uli
  999. ** Added private undefined functions where gcc's -Weffc++ warns otherwise.
  1000. **
  1001. ** Revision 1.14 2011-02-01 09:01:19 joergr
  1002. ** Added "const" specifier to parameter in order to be consistent with the
  1003. ** source file (caused warnings/errors with certain compilers).
  1004. **
  1005. ** Revision 1.13 2010-10-14 13:17:22 joergr
  1006. ** Updated copyright header. Added reference to COPYRIGHT file.
  1007. **
  1008. ** Revision 1.12 2010-10-07 12:54:07 joergr
  1009. ** Fixed minor Doxygen API documentation issues (added backslash in order to
  1010. ** avoid that the short description ends at the first period).
  1011. **
  1012. ** Revision 1.11 2010-06-24 09:21:54 joergr
  1013. ** Revised comment to make clear that the parameter "presID" shall never be 0
  1014. ** for the sendACTIONRequest() method.
  1015. **
  1016. ** Revision 1.10 2010-06-22 15:45:27 joergr
  1017. ** Introduced new enumeration type to be used for closeAssociation().
  1018. ** Further code cleanup. Renamed some methods, variables, types and so on.
  1019. **
  1020. ** Revision 1.9 2010-06-17 17:11:27 joergr
  1021. ** Added preliminary support for N-EVENT-REPORT to DcmSCU. Some further code
  1022. ** cleanups and enhancements. Renamed some methods. Revised documentation.
  1023. **
  1024. ** Revision 1.8 2010-06-09 16:09:01 joergr
  1025. ** Added preliminary support for N-ACTION to DcmSCU. Some further code cleanups
  1026. ** and enhancements.
  1027. **
  1028. ** Revision 1.7 2010-06-08 17:54:12 onken
  1029. ** Added C-FIND functionality to DcmSCU. Some code cleanups. Fixed
  1030. ** memory leak sometimes occuring during association configuration.
  1031. **
  1032. ** Revision 1.6 2010-04-29 16:13:28 onken
  1033. ** Made SCU class independent from dcmtls, i.e. outsourced TLS API. Added
  1034. ** direct API support for sending C-STORE requests. Further API changes and
  1035. ** some bugs fixed.
  1036. **
  1037. ** Revision 1.5 2009-12-21 17:00:32 onken
  1038. ** Fixed API documentation to keep doxygen quiet.
  1039. **
  1040. ** Revision 1.4 2009-12-21 15:33:55 onken
  1041. ** Added documentation and refactored / enhanced some code.
  1042. **
  1043. ** Revision 1.3 2009-12-17 09:12:10 onken
  1044. ** Fixed other scu and scp base class compile issues.
  1045. **
  1046. ** Revision 1.2 2009-12-17 09:05:15 onken
  1047. ** Fixed typo resulting in build failure.
  1048. **
  1049. ** Revision 1.1 2009-12-17 09:02:44 onken
  1050. ** Added base classes for SCU and SCP implementations.
  1051. **
  1052. ** Revision 1.2 2009-12-02 14:26:05 uli
  1053. ** Stop including dcdebug.h which was removed.
  1054. **
  1055. ** Revision 1.1 2008-09-29 13:51:52 onken
  1056. ** Initial checkin of module dcmppscu implementing an MPPS commandline client.
  1057. **
  1058. */