Mercurial > hg > orthanc
comparison OrthancServer/Internals/MoveScp.cpp @ 57:4bc019d2f969 orthanc-renaming
renaming
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 16 Sep 2012 09:22:48 +0200 |
parents | PalanthirServer/Internals/MoveScp.cpp@a15e90e5d6fc |
children | a70bb32802ae |
comparison
equal
deleted
inserted
replaced
56:088c4f23e2c8 | 57:4bc019d2f969 |
---|---|
1 /** | |
2 * Palanthir - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege, | |
4 * Belgium | |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 **/ | |
19 | |
20 | |
21 #include "MoveScp.h" | |
22 | |
23 #include <memory> | |
24 | |
25 #include "../FromDcmtkBridge.h" | |
26 #include "../ToDcmtkBridge.h" | |
27 #include "../../Core/PalanthirException.h" | |
28 | |
29 #include <dcmtk/dcmdata/dcfilefo.h> | |
30 #include <dcmtk/dcmdata/dcmetinf.h> | |
31 #include <dcmtk/dcmdata/dcostrmb.h> | |
32 #include <dcmtk/dcmdata/dcdeftag.h> | |
33 #include <dcmtk/dcmnet/diutil.h> | |
34 | |
35 | |
36 namespace Palanthir | |
37 { | |
38 namespace Internals | |
39 { | |
40 extern OFLogger Logger; | |
41 } | |
42 | |
43 | |
44 namespace | |
45 { | |
46 struct MoveScpData | |
47 { | |
48 std::string target_; | |
49 IMoveRequestHandler* handler_; | |
50 DicomMap input_; | |
51 DcmDataset* lastRequest_; | |
52 unsigned int subOperationCount_; | |
53 unsigned int failureCount_; | |
54 unsigned int warningCount_; | |
55 std::auto_ptr<IMoveRequestIterator> iterator_; | |
56 }; | |
57 | |
58 | |
59 void MoveScpCallback( | |
60 /* in */ | |
61 void *callbackData, | |
62 OFBool cancelled, | |
63 T_DIMSE_C_MoveRQ *request, | |
64 DcmDataset *requestIdentifiers, | |
65 int responseCount, | |
66 /* out */ | |
67 T_DIMSE_C_MoveRSP *response, | |
68 DcmDataset **responseIdentifiers, | |
69 DcmDataset **statusDetail) | |
70 { | |
71 bzero(response, sizeof(T_DIMSE_C_MoveRSP)); | |
72 *statusDetail = NULL; | |
73 *responseIdentifiers = NULL; | |
74 | |
75 MoveScpData& data = *(MoveScpData*) callbackData; | |
76 if (data.lastRequest_ == NULL) | |
77 { | |
78 FromDcmtkBridge::Convert(data.input_, *requestIdentifiers); | |
79 | |
80 try | |
81 { | |
82 data.iterator_.reset(data.handler_->Handle(data.target_, data.input_)); | |
83 data.subOperationCount_ = data.iterator_->GetSubOperationCount(); | |
84 data.failureCount_ = 0; | |
85 data.warningCount_ = 0; | |
86 } | |
87 catch (PalanthirException& e) | |
88 { | |
89 // Internal error! | |
90 OFLOG_ERROR(Internals::Logger, "IMoveRequestHandler Failed: " << e.What()); | |
91 response->DimseStatus = STATUS_MOVE_Failed_UnableToProcess; | |
92 return; | |
93 } | |
94 | |
95 data.lastRequest_ = requestIdentifiers; | |
96 } | |
97 else if (data.lastRequest_ != requestIdentifiers) | |
98 { | |
99 // Internal error! | |
100 response->DimseStatus = STATUS_MOVE_Failed_UnableToProcess; | |
101 return; | |
102 } | |
103 | |
104 if (data.subOperationCount_ == 0) | |
105 { | |
106 response->DimseStatus = STATUS_Success; | |
107 } | |
108 else | |
109 { | |
110 IMoveRequestIterator::Status status; | |
111 | |
112 try | |
113 { | |
114 status = data.iterator_->DoNext(); | |
115 } | |
116 catch (PalanthirException& e) | |
117 { | |
118 // Internal error! | |
119 OFLOG_ERROR(Internals::Logger, "IMoveRequestHandler Failed: " << e.What()); | |
120 response->DimseStatus = STATUS_MOVE_Failed_UnableToProcess; | |
121 return; | |
122 } | |
123 | |
124 if (status == IMoveRequestIterator::Status_Failure) | |
125 { | |
126 data.failureCount_++; | |
127 } | |
128 else if (status == IMoveRequestIterator::Status_Warning) | |
129 { | |
130 data.warningCount_++; | |
131 } | |
132 | |
133 if (responseCount < static_cast<int>(data.subOperationCount_)) | |
134 { | |
135 response->DimseStatus = STATUS_Pending; | |
136 } | |
137 else | |
138 { | |
139 response->DimseStatus = STATUS_Success; | |
140 } | |
141 } | |
142 | |
143 response->NumberOfRemainingSubOperations = data.subOperationCount_ - responseCount; | |
144 response->NumberOfCompletedSubOperations = responseCount; | |
145 response->NumberOfFailedSubOperations = data.failureCount_; | |
146 response->NumberOfWarningSubOperations = data.warningCount_; | |
147 } | |
148 } | |
149 | |
150 | |
151 OFCondition Internals::moveScp(T_ASC_Association * assoc, | |
152 T_DIMSE_Message * msg, | |
153 T_ASC_PresentationContextID presID, | |
154 IMoveRequestHandler& handler) | |
155 { | |
156 MoveScpData data; | |
157 data.target_ = std::string(msg->msg.CMoveRQ.MoveDestination); | |
158 data.lastRequest_ = NULL; | |
159 data.handler_ = &handler; | |
160 | |
161 OFCondition cond = DIMSE_moveProvider(assoc, presID, &msg->msg.CMoveRQ, | |
162 MoveScpCallback, &data, | |
163 /*opt_blockMode*/ DIMSE_BLOCKING, | |
164 /*opt_dimse_timeout*/ 0); | |
165 | |
166 // if some error occured, dump corresponding information and remove the outfile if necessary | |
167 if (cond.bad()) | |
168 { | |
169 OFString temp_str; | |
170 OFLOG_ERROR(Internals::Logger, "Move SCP Failed: " << DimseCondition::dump(temp_str, cond)); | |
171 } | |
172 | |
173 return cond; | |
174 } | |
175 } |