Mercurial > hg > orthanc
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(); |