comparison Core/DicomNetworking/Internals/GetScp.cpp @ 3953:620e87e9e816 c-get

c-get: fixing memory with failedUIDs_
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 20 May 2020 09:19:35 +0200
parents 4f78da5613a1
children 67b457283499
comparison
equal deleted inserted replaced
3952:4f09a6a2b369 3953:620e87e9e816
38 This file is based on portions of the following project: 38 This file is based on portions of the following project:
39 39
40 Program: DCMTK 3.6.0 40 Program: DCMTK 3.6.0
41 Module: http://dicom.offis.de/dcmtk.php.en 41 Module: http://dicom.offis.de/dcmtk.php.en
42 42
43 Copyright (C) 1994-2011, OFFIS e.V. 43 Copyright (C) 1994-2011, OFFIS e.V.
44 All rights reserved. 44 All rights reserved.
45 45
46 This software and supporting documentation were developed by 46 This software and supporting documentation were developed by
47 47
48 OFFIS e.V. 48 OFFIS e.V.
49 R&D Division Health 49 R&D Division Health
50 Escherweg 2 50 Escherweg 2
51 26121 Oldenburg, Germany 51 26121 Oldenburg, Germany
52 52
53 Redistribution and use in source and binary forms, with or without 53 Redistribution and use in source and binary forms, with or without
54 modification, are permitted provided that the following conditions 54 modification, are permitted provided that the following conditions
55 are met: 55 are met:
56 56
57 - Redistributions of source code must retain the above copyright 57 - Redistributions of source code must retain the above copyright
58 notice, this list of conditions and the following disclaimer. 58 notice, this list of conditions and the following disclaimer.
59 59
60 - Redistributions in binary form must reproduce the above copyright 60 - Redistributions in binary form must reproduce the above copyright
61 notice, this list of conditions and the following disclaimer in the 61 notice, this list of conditions and the following disclaimer in the
62 documentation and/or other materials provided with the distribution. 62 documentation and/or other materials provided with the distribution.
63 63
64 - Neither the name of OFFIS nor the names of its contributors may be 64 - Neither the name of OFFIS nor the names of its contributors may be
65 used to endorse or promote products derived from this software 65 used to endorse or promote products derived from this software
66 without specific prior written permission. 66 without specific prior written permission.
67 67
68 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 68 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
69 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 69 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
70 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 70 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
71 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 71 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
72 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 72 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
73 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 73 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
74 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 74 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
75 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 75 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
76 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 76 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 77 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
78 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 78 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79 79
80 =========================================================================*/ 80 =========================================================================*/
81 81
82 82
83 #include "../../PrecompiledHeaders.h" 83 #include "../../PrecompiledHeaders.h"
84 #include <dcmtk/dcmnet/diutil.h> 84 #include <dcmtk/dcmnet/diutil.h>
85 #include <dcmtk/dcmdata/dcdeftag.h> 85 #include <dcmtk/dcmdata/dcdeftag.h>
121 lastRequest_ = NULL; 121 lastRequest_ = NULL;
122 assoc_ = NULL; 122 assoc_ = NULL;
123 }; 123 };
124 }; 124 };
125 125
126 void BuildFailedInstanceList(const char* failedUIDs, DcmDataset ** rspIds) 126 static DcmDataset *BuildFailedInstanceList(const std::string& failedUIDs)
127 { 127 {
128 OFBool ok; 128 if (failedUIDs.empty())
129 129 {
130 if (failedUIDs != NULL) 130 return NULL;
131 { 131 }
132 *rspIds = new DcmDataset(); 132 else
133 ok = DU_putStringDOElement(*rspIds, DCM_FailedSOPInstanceUIDList, failedUIDs); 133 {
134 if (!ok) 134 std::unique_ptr<DcmDataset> rspIds(new DcmDataset());
135 {
136 LOG (ERROR) << "getSCP: failed to build DCM_FailedSOPInstanceUIDList";
137 }
138 135
136 if (!DU_putStringDOElement(rspIds.get(), DCM_FailedSOPInstanceUIDList, failedUIDs.c_str()))
137 {
138 throw OrthancException(ErrorCode_InternalError,
139 "getSCP: failed to build DCM_FailedSOPInstanceUIDList");
140 }
141
142 return rspIds.release();
139 } 143 }
140 } 144 }
141 145
142 void GetScpCallback( 146 static void GetScpCallback(
143 /* in */ 147 /* in */
144 void *callbackData, 148 void *callbackData,
145 OFBool cancelled, 149 OFBool cancelled,
146 T_DIMSE_C_GetRQ *request, 150 T_DIMSE_C_GetRQ *request,
147 DcmDataset *requestIdentifiers, 151 DcmDataset *requestIdentifiers,
162 FromDcmtkBridge::ExtractDicomSummary(input, *requestIdentifiers); 166 FromDcmtkBridge::ExtractDicomSummary(input, *requestIdentifiers);
163 167
164 try 168 try
165 { 169 {
166 if(!data.handler_->Handle(input, data.remoteIp_, data.remoteAet_, 170 if(!data.handler_->Handle(input, data.remoteIp_, data.remoteAet_,
167 data.calledAet_)) 171 data.calledAet_))
168 { 172 {
169 response->DimseStatus = STATUS_GET_Failed_UnableToProcess; 173 response->DimseStatus = STATUS_GET_Failed_UnableToProcess;
170 return; 174 return;
171 } 175 }
172 } 176 }
221 } 225 }
222 else 226 else
223 { 227 {
224 response->DimseStatus = STATUS_GET_Failed_UnableToProcess; 228 response->DimseStatus = STATUS_GET_Failed_UnableToProcess;
225 229
226 if (data.handler_->nFailed() > 0 || data.handler_->warningCount() > 0) 230 if (data.handler_->nFailed() > 0 ||
231 data.handler_->warningCount() > 0)
227 { 232 {
228 response->DimseStatus = STATUS_GET_Warning_SubOperationsCompleteOneOrMoreFailures; 233 response->DimseStatus = STATUS_GET_Warning_SubOperationsCompleteOneOrMoreFailures;
229 } 234 }
230 /* 235 /*
231 * if all the sub-operations failed then we need to generate a failed or refused status. 236 * if all the sub-operations failed then we need to generate
232 * cf. DICOM part 4, C.4.3.3.1 237 * a failed or refused status. cf. DICOM part 4, C.4.3.3.1
233 * we choose to generate a "Refused - Out of Resources - Unable to perform suboperations" status. 238 * we choose to generate a "Refused - Out of Resources -
239 * Unable to perform suboperations" status.
234 */ 240 */
235 if ((data.handler_->nFailed() > 0) && ((data.handler_->nCompleted() + data.handler_->warningCount()) == 0)) 241 if ((data.handler_->nFailed() > 0) &&
242 ((data.handler_->nCompleted() + data.handler_->warningCount()) == 0))
236 { 243 {
237 response->DimseStatus = STATUS_GET_Refused_OutOfResourcesSubOperations; 244 response->DimseStatus = STATUS_GET_Refused_OutOfResourcesSubOperations;
238 } 245 }
239 246
240 BuildFailedInstanceList(data.handler_->failedUids(), responseIdentifiers); 247 *responseIdentifiers = BuildFailedInstanceList(data.handler_->failedUids());
241 } 248 }
242 } 249 }
243 250
244 response->NumberOfRemainingSubOperations = data.handler_->nRemaining(); 251 response->NumberOfRemainingSubOperations = data.handler_->nRemaining();
245 response->NumberOfCompletedSubOperations = data.handler_->nCompleted(); 252 response->NumberOfCompletedSubOperations = data.handler_->nCompleted();
246 response->NumberOfFailedSubOperations = data.handler_->nFailed(); 253 response->NumberOfFailedSubOperations = data.handler_->nFailed();
247 response->NumberOfWarningSubOperations = data.handler_->warningCount(); 254 response->NumberOfWarningSubOperations = data.handler_->warningCount();
248 } 255 }
249
250 } 256 }
251 257
252 OFCondition Internals::getScp(T_ASC_Association * assoc, 258 OFCondition Internals::getScp(T_ASC_Association * assoc,
253 T_DIMSE_Message * msg, 259 T_DIMSE_Message * msg,
254 T_ASC_PresentationContextID presID, 260 T_ASC_PresentationContextID presID,
255 IGetRequestHandler& handler, 261 IGetRequestHandler& handler,
256 std::string remoteIp, 262 std::string remoteIp,
257 std::string remoteAet, 263 std::string remoteAet,
258 std::string calledAet) 264 std::string calledAet,
265 int timeout)
259 { 266 {
260
261 GetScpData data; 267 GetScpData data;
262 data.lastRequest_ = NULL; 268 data.lastRequest_ = NULL;
263 data.handler_ = &handler; 269 data.handler_ = &handler;
264 data.assoc_ = assoc; 270 data.assoc_ = assoc;
265 data.remoteIp_ = remoteIp; 271 data.remoteIp_ = remoteIp;
266 data.remoteAet_ = remoteAet; 272 data.remoteAet_ = remoteAet;
267 data.calledAet_ = calledAet; 273 data.calledAet_ = calledAet;
268 274
269
270 OFCondition cond = DIMSE_getProvider(assoc, presID, &msg->msg.CGetRQ, 275 OFCondition cond = DIMSE_getProvider(assoc, presID, &msg->msg.CGetRQ,
271 GetScpCallback, &data, 276 GetScpCallback, &data,
272 /*opt_blockMode*/ DIMSE_BLOCKING, 277 /*opt_blockMode*/ (timeout ? DIMSE_NONBLOCKING : DIMSE_BLOCKING),
273 /*opt_dimse_timeout*/ 0); 278 /*opt_dimse_timeout*/ timeout);
274 279
275 // if some error occured, dump corresponding information and remove the outfile if necessary 280 // if some error occured, dump corresponding information and remove the outfile if necessary
276 if (cond.bad()) 281 if (cond.bad())
277 { 282 {
278 OFString temp_str; 283 OFString temp_str;
279 LOG(ERROR) << "Get SCP Failed: " << cond.text(); 284 LOG(ERROR) << "Get SCP Failed: " << cond.text();