comparison Core/DicomNetworking/DicomControlUserConnection.cpp @ 3826:e82bd07c384e

putting DicomAssociation behind pimpl
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 10 Apr 2020 16:12:10 +0200
parents 4570c57668a8
children 3d1bb2193832
comparison
equal deleted inserted replaced
3825:4570c57668a8 3826:e82bd07c384e
32 32
33 33
34 #include "../PrecompiledHeaders.h" 34 #include "../PrecompiledHeaders.h"
35 #include "DicomControlUserConnection.h" 35 #include "DicomControlUserConnection.h"
36 36
37 #include "../DicomParsing/FromDcmtkBridge.h"
37 #include "../Logging.h" 38 #include "../Logging.h"
38 #include "../OrthancException.h" 39 #include "../OrthancException.h"
39 #include "../DicomParsing/FromDcmtkBridge.h" 40 #include "DicomAssociation.h"
40 41
41 #include <dcmtk/dcmdata/dcdeftag.h> 42 #include <dcmtk/dcmdata/dcdeftag.h>
42 #include <dcmtk/dcmnet/diutil.h> 43 #include <dcmtk/dcmnet/diutil.h>
43 44
44 namespace Orthanc 45 namespace Orthanc
222 223
223 224
224 225
225 void DicomControlUserConnection::SetupPresentationContexts() 226 void DicomControlUserConnection::SetupPresentationContexts()
226 { 227 {
227 association_.ProposeGenericPresentationContext(UID_VerificationSOPClass); 228 association_->ProposeGenericPresentationContext(UID_VerificationSOPClass);
228 association_.ProposeGenericPresentationContext(UID_FINDPatientRootQueryRetrieveInformationModel); 229 association_->ProposeGenericPresentationContext(UID_FINDPatientRootQueryRetrieveInformationModel);
229 association_.ProposeGenericPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel); 230 association_->ProposeGenericPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel);
230 association_.ProposeGenericPresentationContext(UID_MOVEStudyRootQueryRetrieveInformationModel); 231 association_->ProposeGenericPresentationContext(UID_MOVEStudyRootQueryRetrieveInformationModel);
231 association_.ProposeGenericPresentationContext(UID_FINDModalityWorklistInformationModel); 232 association_->ProposeGenericPresentationContext(UID_FINDModalityWorklistInformationModel);
232 } 233 }
233 234
234 235
235 void DicomControlUserConnection::FindInternal(DicomFindAnswers& answers, 236 void DicomControlUserConnection::FindInternal(DicomFindAnswers& answers,
236 DcmDataset* dataset, 237 DcmDataset* dataset,
238 bool isWorklist, 239 bool isWorklist,
239 const char* level) 240 const char* level)
240 { 241 {
241 assert(isWorklist ^ (level != NULL)); 242 assert(isWorklist ^ (level != NULL));
242 243
243 association_.Open(parameters_); 244 association_->Open(parameters_);
244 245
245 FindPayload payload; 246 FindPayload payload;
246 payload.answers = &answers; 247 payload.answers = &answers;
247 payload.level = level; 248 payload.level = level;
248 payload.isWorklist = isWorklist; 249 payload.isWorklist = isWorklist;
249 250
250 // Figure out which of the accepted presentation contexts should be used 251 // Figure out which of the accepted presentation contexts should be used
251 int presID = ASC_findAcceptedPresentationContextID( 252 int presID = ASC_findAcceptedPresentationContextID(
252 &association_.GetDcmtkAssociation(), sopClass); 253 &association_->GetDcmtkAssociation(), sopClass);
253 if (presID == 0) 254 if (presID == 0)
254 { 255 {
255 throw OrthancException(ErrorCode_DicomFindUnavailable, 256 throw OrthancException(ErrorCode_DicomFindUnavailable,
256 "Remote AET is " + parameters_.GetRemoteApplicationEntityTitle()); 257 "Remote AET is " + parameters_.GetRemoteApplicationEntityTitle());
257 } 258 }
258 259
259 T_DIMSE_C_FindRQ request; 260 T_DIMSE_C_FindRQ request;
260 memset(&request, 0, sizeof(request)); 261 memset(&request, 0, sizeof(request));
261 request.MessageID = association_.GetDcmtkAssociation().nextMsgID++; 262 request.MessageID = association_->GetDcmtkAssociation().nextMsgID++;
262 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN); 263 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN);
263 request.Priority = DIMSE_PRIORITY_MEDIUM; 264 request.Priority = DIMSE_PRIORITY_MEDIUM;
264 request.DataSetType = DIMSE_DATASET_PRESENT; 265 request.DataSetType = DIMSE_DATASET_PRESENT;
265 266
266 T_DIMSE_C_FindRSP response; 267 T_DIMSE_C_FindRSP response;
269 #if DCMTK_VERSION_NUMBER >= 364 270 #if DCMTK_VERSION_NUMBER >= 364
270 int responseCount; 271 int responseCount;
271 #endif 272 #endif
272 273
273 OFCondition cond = DIMSE_findUser( 274 OFCondition cond = DIMSE_findUser(
274 &association_.GetDcmtkAssociation(), presID, &request, dataset, 275 &association_->GetDcmtkAssociation(), presID, &request, dataset,
275 #if DCMTK_VERSION_NUMBER >= 364 276 #if DCMTK_VERSION_NUMBER >= 364
276 responseCount, 277 responseCount,
277 #endif 278 #endif
278 FindCallback, &payload, 279 FindCallback, &payload,
279 /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), 280 /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING),
321 322
322 void DicomControlUserConnection::MoveInternal(const std::string& targetAet, 323 void DicomControlUserConnection::MoveInternal(const std::string& targetAet,
323 ResourceType level, 324 ResourceType level,
324 const DicomMap& fields) 325 const DicomMap& fields)
325 { 326 {
326 association_.Open(parameters_); 327 association_->Open(parameters_);
327 328
328 std::unique_ptr<ParsedDicomFile> query( 329 std::unique_ptr<ParsedDicomFile> query(
329 ConvertQueryFields(fields, parameters_.GetRemoteManufacturer())); 330 ConvertQueryFields(fields, parameters_.GetRemoteManufacturer()));
330 DcmDataset* dataset = query->GetDcmtkObject().getDataset(); 331 DcmDataset* dataset = query->GetDcmtkObject().getDataset();
331 332
351 default: 352 default:
352 throw OrthancException(ErrorCode_ParameterOutOfRange); 353 throw OrthancException(ErrorCode_ParameterOutOfRange);
353 } 354 }
354 355
355 // Figure out which of the accepted presentation contexts should be used 356 // Figure out which of the accepted presentation contexts should be used
356 int presID = ASC_findAcceptedPresentationContextID(&association_.GetDcmtkAssociation(), sopClass); 357 int presID = ASC_findAcceptedPresentationContextID(&association_->GetDcmtkAssociation(), sopClass);
357 if (presID == 0) 358 if (presID == 0)
358 { 359 {
359 throw OrthancException(ErrorCode_DicomMoveUnavailable, 360 throw OrthancException(ErrorCode_DicomMoveUnavailable,
360 "Remote AET is " + parameters_.GetRemoteApplicationEntityTitle()); 361 "Remote AET is " + parameters_.GetRemoteApplicationEntityTitle());
361 } 362 }
362 363
363 T_DIMSE_C_MoveRQ request; 364 T_DIMSE_C_MoveRQ request;
364 memset(&request, 0, sizeof(request)); 365 memset(&request, 0, sizeof(request));
365 request.MessageID = association_.GetDcmtkAssociation().nextMsgID++; 366 request.MessageID = association_->GetDcmtkAssociation().nextMsgID++;
366 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN); 367 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN);
367 request.Priority = DIMSE_PRIORITY_MEDIUM; 368 request.Priority = DIMSE_PRIORITY_MEDIUM;
368 request.DataSetType = DIMSE_DATASET_PRESENT; 369 request.DataSetType = DIMSE_DATASET_PRESENT;
369 strncpy(request.MoveDestination, targetAet.c_str(), DIC_AE_LEN); 370 strncpy(request.MoveDestination, targetAet.c_str(), DIC_AE_LEN);
370 371
371 T_DIMSE_C_MoveRSP response; 372 T_DIMSE_C_MoveRSP response;
372 DcmDataset* statusDetail = NULL; 373 DcmDataset* statusDetail = NULL;
373 DcmDataset* responseIdentifiers = NULL; 374 DcmDataset* responseIdentifiers = NULL;
374 OFCondition cond = DIMSE_moveUser( 375 OFCondition cond = DIMSE_moveUser(
375 &association_.GetDcmtkAssociation(), presID, &request, dataset, NULL, NULL, 376 &association_->GetDcmtkAssociation(), presID, &request, dataset, NULL, NULL,
376 /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), 377 /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING),
377 /*opt_dimse_timeout*/ parameters_.GetTimeout(), 378 /*opt_dimse_timeout*/ parameters_.GetTimeout(),
378 &association_.GetDcmtkNetwork(), NULL, NULL, 379 &association_->GetDcmtkNetwork(), NULL, NULL,
379 &response, &statusDetail, &responseIdentifiers); 380 &response, &statusDetail, &responseIdentifiers);
380 381
381 if (statusDetail) 382 if (statusDetail)
382 { 383 {
383 delete statusDetail; 384 delete statusDetail;
420 } 421 }
421 } 422 }
422 423
423 424
424 DicomControlUserConnection::DicomControlUserConnection(const DicomAssociationParameters& params) : 425 DicomControlUserConnection::DicomControlUserConnection(const DicomAssociationParameters& params) :
425 parameters_(params) 426 parameters_(params),
427 association_(new DicomAssociation)
426 { 428 {
427 SetupPresentationContexts(); 429 SetupPresentationContexts();
428 } 430 }
429 431
430 432
431 bool DicomControlUserConnection::Echo() 433 bool DicomControlUserConnection::Echo()
432 { 434 {
433 association_.Open(parameters_); 435 association_->Open(parameters_);
434 436
435 DIC_US status; 437 DIC_US status;
436 DicomAssociation::CheckCondition( 438 DicomAssociation::CheckCondition(
437 DIMSE_echoUser(&association_.GetDcmtkAssociation(), 439 DIMSE_echoUser(&association_->GetDcmtkAssociation(),
438 association_.GetDcmtkAssociation().nextMsgID++, 440 association_->GetDcmtkAssociation().nextMsgID++,
439 /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING), 441 /*opt_blockMode*/ (parameters_.HasTimeout() ? DIMSE_NONBLOCKING : DIMSE_BLOCKING),
440 /*opt_dimse_timeout*/ parameters_.GetTimeout(), 442 /*opt_dimse_timeout*/ parameters_.GetTimeout(),
441 &status, NULL), 443 &status, NULL),
442 parameters_, "C-ECHO"); 444 parameters_, "C-ECHO");
443 445