comparison OrthancServer/DicomProtocol/DicomUserConnection.cpp @ 1907:5011a597b6ce

Support of Move Originator Message ID (0000,1031) in C-Store responses driven by C-Move
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 07 Jan 2016 11:28:19 +0100
parents b1291df2f780
children 84c7eaeb5244
comparison
equal deleted inserted replaced
1906:d7c1cb559431 1907:5011a597b6ce
146 return assoc_ != NULL; 146 return assoc_ != NULL;
147 } 147 }
148 148
149 void CheckIsOpen() const; 149 void CheckIsOpen() const;
150 150
151 void Store(DcmInputStream& is, DicomUserConnection& connection); 151 void Store(DcmInputStream& is,
152 DicomUserConnection& connection,
153 uint16_t moveMessageID);
152 }; 154 };
153 155
154 156
155 static void Check(const OFCondition& cond) 157 static void Check(const OFCondition& cond)
156 { 158 {
249 syntax == UID_BigEndianExplicitTransferSyntax || 251 syntax == UID_BigEndianExplicitTransferSyntax ||
250 syntax == UID_LittleEndianImplicitTransferSyntax); 252 syntax == UID_LittleEndianImplicitTransferSyntax);
251 } 253 }
252 254
253 255
254 void DicomUserConnection::PImpl::Store(DcmInputStream& is, DicomUserConnection& connection) 256 void DicomUserConnection::PImpl::Store(DcmInputStream& is,
257 DicomUserConnection& connection,
258 uint16_t moveMessageID)
255 { 259 {
256 CheckIsOpen(); 260 CheckIsOpen();
257 261
258 DcmFileFormat dcmff; 262 DcmFileFormat dcmff;
259 Check(dcmff.read(is, EXS_Unknown, EGL_noChange, DCM_MaxReadLength)); 263 Check(dcmff.read(is, EXS_Unknown, EGL_noChange, DCM_MaxReadLength));
323 if (!modalityName) modalityName = "unknown SOP class"; 327 if (!modalityName) modalityName = "unknown SOP class";
324 throw OrthancException(ErrorCode_NoPresentationContext); 328 throw OrthancException(ErrorCode_NoPresentationContext);
325 } 329 }
326 330
327 // Prepare the transmission of data 331 // Prepare the transmission of data
328 T_DIMSE_C_StoreRQ req; 332 T_DIMSE_C_StoreRQ request;
329 memset(&req, 0, sizeof(req)); 333 memset(&request, 0, sizeof(request));
330 req.MessageID = assoc_->nextMsgID++; 334 request.MessageID = assoc_->nextMsgID++;
331 strcpy(req.AffectedSOPClassUID, sopClass); 335 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN);
332 strcpy(req.AffectedSOPInstanceUID, sopInstance); 336 request.Priority = DIMSE_PRIORITY_MEDIUM;
333 req.DataSetType = DIMSE_DATASET_PRESENT; 337 request.DataSetType = DIMSE_DATASET_PRESENT;
334 req.Priority = DIMSE_PRIORITY_MEDIUM; 338 strncpy(request.AffectedSOPInstanceUID, sopInstance, DIC_UI_LEN);
339
340 strncpy(request.MoveOriginatorApplicationEntityTitle,
341 connection.GetLocalApplicationEntityTitle().c_str(), DIC_AE_LEN);
342 request.opts = O_STORE_MOVEORIGINATORAETITLE;
343
344 if (moveMessageID != 0)
345 {
346 request.MoveOriginatorID = moveMessageID; // The type DIC_US is an alias for uint16_t
347 request.opts |= O_STORE_MOVEORIGINATORID;
348 }
335 349
336 // Finally conduct transmission of data 350 // Finally conduct transmission of data
337 T_DIMSE_C_StoreRSP rsp; 351 T_DIMSE_C_StoreRSP rsp;
338 DcmDataset* statusDetail = NULL; 352 DcmDataset* statusDetail = NULL;
339 Check(DIMSE_storeUser(assoc_, presID, &req, 353 Check(DIMSE_storeUser(assoc_, presID, &request,
340 NULL, dcmff.getDataset(), /*progressCallback*/ NULL, NULL, 354 NULL, dcmff.getDataset(), /*progressCallback*/ NULL, NULL,
341 /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ dimseTimeout_, 355 /*opt_blockMode*/ DIMSE_BLOCKING, /*opt_dimse_timeout*/ dimseTimeout_,
342 &rsp, &statusDetail, NULL)); 356 &rsp, &statusDetail, NULL));
343 357
344 if (statusDetail != NULL) 358 if (statusDetail != NULL)
509 } 523 }
510 524
511 T_DIMSE_C_FindRQ request; 525 T_DIMSE_C_FindRQ request;
512 memset(&request, 0, sizeof(request)); 526 memset(&request, 0, sizeof(request));
513 request.MessageID = association->nextMsgID++; 527 request.MessageID = association->nextMsgID++;
514 strcpy(request.AffectedSOPClassUID, sopClass); 528 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN);
529 request.Priority = DIMSE_PRIORITY_MEDIUM;
515 request.DataSetType = DIMSE_DATASET_PRESENT; 530 request.DataSetType = DIMSE_DATASET_PRESENT;
516 request.Priority = DIMSE_PRIORITY_MEDIUM;
517 531
518 T_DIMSE_C_FindRSP response; 532 T_DIMSE_C_FindRSP response;
519 DcmDataset* statusDetail = NULL; 533 DcmDataset* statusDetail = NULL;
520 OFCondition cond = DIMSE_findUser(association, presID, &request, dataset, 534 OFCondition cond = DIMSE_findUser(association, presID, &request, dataset,
521 FindCallback, &payload, 535 FindCallback, &payload,
676 } 690 }
677 691
678 T_DIMSE_C_MoveRQ request; 692 T_DIMSE_C_MoveRQ request;
679 memset(&request, 0, sizeof(request)); 693 memset(&request, 0, sizeof(request));
680 request.MessageID = pimpl_->assoc_->nextMsgID++; 694 request.MessageID = pimpl_->assoc_->nextMsgID++;
681 strcpy(request.AffectedSOPClassUID, sopClass); 695 strncpy(request.AffectedSOPClassUID, sopClass, DIC_UI_LEN);
696 request.Priority = DIMSE_PRIORITY_MEDIUM;
682 request.DataSetType = DIMSE_DATASET_PRESENT; 697 request.DataSetType = DIMSE_DATASET_PRESENT;
683 request.Priority = DIMSE_PRIORITY_MEDIUM; 698 strncpy(request.MoveDestination, targetAet.c_str(), DIC_AE_LEN);
684 strncpy(request.MoveDestination, targetAet.c_str(), sizeof(DIC_AE) / sizeof(char));
685 699
686 T_DIMSE_C_MoveRSP response; 700 T_DIMSE_C_MoveRSP response;
687 DcmDataset* statusDetail = NULL; 701 DcmDataset* statusDetail = NULL;
688 DcmDataset* responseIdentifiers = NULL; 702 DcmDataset* responseIdentifiers = NULL;
689 OFCondition cond = DIMSE_moveUser(pimpl_->assoc_, presID, &request, dataset.get(), 703 OFCondition cond = DIMSE_moveUser(pimpl_->assoc_, presID, &request, dataset.get(),
918 bool DicomUserConnection::IsOpen() const 932 bool DicomUserConnection::IsOpen() const
919 { 933 {
920 return pimpl_->IsOpen(); 934 return pimpl_->IsOpen();
921 } 935 }
922 936
923 void DicomUserConnection::Store(const char* buffer, size_t size) 937 void DicomUserConnection::Store(const char* buffer,
938 size_t size,
939 uint16_t moveMessageID)
924 { 940 {
925 // Prepare an input stream for the memory buffer 941 // Prepare an input stream for the memory buffer
926 DcmInputBufferStream is; 942 DcmInputBufferStream is;
927 if (size > 0) 943 if (size > 0)
928 is.setBuffer(buffer, size); 944 is.setBuffer(buffer, size);
929 is.setEos(); 945 is.setEos();
930 946
931 pimpl_->Store(is, *this); 947 pimpl_->Store(is, *this, moveMessageID);
932 } 948 }
933 949
934 void DicomUserConnection::Store(const std::string& buffer) 950 void DicomUserConnection::Store(const std::string& buffer,
951 uint16_t moveMessageID)
935 { 952 {
936 if (buffer.size() > 0) 953 if (buffer.size() > 0)
937 Store(reinterpret_cast<const char*>(&buffer[0]), buffer.size()); 954 Store(reinterpret_cast<const char*>(&buffer[0]), buffer.size(), moveMessageID);
938 else 955 else
939 Store(NULL, 0); 956 Store(NULL, 0, moveMessageID);
940 } 957 }
941 958
942 void DicomUserConnection::StoreFile(const std::string& path) 959 void DicomUserConnection::StoreFile(const std::string& path,
960 uint16_t moveMessageID)
943 { 961 {
944 // Prepare an input stream for the file 962 // Prepare an input stream for the file
945 DcmInputFileStream is(path.c_str()); 963 DcmInputFileStream is(path.c_str());
946 pimpl_->Store(is, *this); 964 pimpl_->Store(is, *this, moveMessageID);
947 } 965 }
948 966
949 bool DicomUserConnection::Echo() 967 bool DicomUserConnection::Echo()
950 { 968 {
951 CheckIsOpen(); 969 CheckIsOpen();