ctkDcmSCU.h 58 KB

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