1 /*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18 /*
19 basically, given an initial byte, construct the appropriate PDU.
20 this way, the event loop doesn't have to know about all the different PDU types.
21
22 name and date: 25 Sept 2010 mmr
23
24 Updte on 27 sept 2010 mmr: since this is where all PDUs are included, also use this
25 class to construct specific instances of PDUs, and return the BasePDU class.
26 */
27 #include "gdcmPDUFactory.h"
28 #include "gdcmAAbortPDU.h"
29 #include "gdcmAAssociateACPDU.h"
30 #include "gdcmAAssociateRJPDU.h"
31 #include "gdcmAAssociateRQPDU.h"
32 #include "gdcmAReleaseRPPDU.h"
33 #include "gdcmAReleaseRQPDU.h"
34 #include "gdcmPDataTFPDU.h"
35 #include "gdcmCompositeMessageFactory.h"
36 #include "gdcmNormalizedMessageFactory.h"
37 #include "gdcmBaseRootQuery.h"
38 #include "gdcmBasePDU.h"
39
40 namespace gdcm
41 {
42 namespace network
43 {
44
45 //eventually needs to be smartpointer'd
ConstructPDU(uint8_t itemtype)46 BasePDU* PDUFactory::ConstructPDU(uint8_t itemtype)
47 {
48 BasePDU* thePDU = nullptr;
49 switch (itemtype)
50 {
51 case 0x01:
52 thePDU = new AAssociateRQPDU;
53 break;
54 case 0x02:
55 thePDU = new AAssociateACPDU;
56 break;
57 case 0x03:
58 thePDU = new AAssociateRJPDU;
59 break;
60 case 0x04:
61 thePDU = new PDataTFPDU;
62 break;
63 case 0x05:
64 thePDU = new AReleaseRQPDU;
65 break;
66 case 0x06:
67 thePDU = new AReleaseRPPDU;
68 break;
69 case 0x07:
70 thePDU = new AAbortPDU;
71 break;
72 //default is that the PDU remains null
73 }
74 if( !thePDU )
75 {
76 gdcmErrorMacro( "Could not construct PDU for itemtype: " << (int)itemtype );
77 }
78 return thePDU;
79 }
80
81 //determine which event was received by the PDU type
DetermineEventByPDU(const BasePDU * inPDU)82 EEventID PDUFactory::DetermineEventByPDU(const BasePDU* inPDU)
83 {
84 if(inPDU)
85 {
86 const AAssociateRQPDU* theAAssociateRQPDU = dynamic_cast<const AAssociateRQPDU*>(inPDU);
87 if (theAAssociateRQPDU != nullptr)
88 {
89 return eAASSOCIATE_RQPDUreceived;
90 }
91 const AAssociateACPDU* theAAssociateACPDU = dynamic_cast<const AAssociateACPDU*>(inPDU);
92 if (theAAssociateACPDU != nullptr)
93 {
94 return eASSOCIATE_ACPDUreceived;
95 }
96 const AAssociateRJPDU* theAAssociateRJPDU = dynamic_cast<const AAssociateRJPDU*>(inPDU);
97 if (theAAssociateRJPDU != nullptr)
98 {
99 return eASSOCIATE_RJPDUreceived;
100 }
101 const PDataTFPDU* thePDataTFPDU = dynamic_cast<const PDataTFPDU*>(inPDU);
102 if (thePDataTFPDU != nullptr)
103 {
104 ///
105 const PresentationDataValue &pdv = thePDataTFPDU->GetPresentationDataValue(0);
106 (void)pdv;
107 #if 0
108 int mh = pdv.GetMessageHeader();
109 if( mh == 3 )
110 {
111 // E.2 MESSAGE CONTROL HEADER ENCODING
112 // If bit 1 is set to 1, the following fragment shall contain the last
113 // fragment of a Message Data Set or of a Message Command.
114 std::cout << "This was the last fragment of the message data set" << std::endl;
115 }
116 #endif
117 return ePDATATFPDU;
118 }
119 const AReleaseRQPDU* theAReleaseRQPDU = dynamic_cast<const AReleaseRQPDU*>(inPDU);
120 if (theAReleaseRQPDU != nullptr)
121 {
122 return eARELEASE_RQPDUReceivedOpen;
123 }
124 const AReleaseRPPDU* theAReleaseRPPDU = dynamic_cast<const AReleaseRPPDU*>(inPDU);
125 if (theAReleaseRPPDU != nullptr)
126 {
127 return eARELEASE_RPPDUReceived;
128 }
129 const AAbortPDU* theAAbortPDU = dynamic_cast<const AAbortPDU*>(inPDU);
130 if (theAAbortPDU != nullptr)
131 {
132 return eAABORTPDUReceivedOpen;
133 }
134 }
135 return eEventDoesNotExist;
136 }
137
ConstructReleasePDU()138 BasePDU* PDUFactory::ConstructReleasePDU()
139 {
140 AReleaseRQPDU* theAReleaseRQPDU = new AReleaseRQPDU();
141
142 return theAReleaseRQPDU;
143 }
ConstructAbortPDU()144 BasePDU* PDUFactory::ConstructAbortPDU()
145 {
146 AAbortPDU* theAAbortPDU = new AAbortPDU();
147
148 return theAAbortPDU;
149 }
CreateCEchoPDU(const ULConnection & inConnection)150 std::vector<BasePDU*> PDUFactory::CreateCEchoPDU(const ULConnection& inConnection)
151 {
152 std::vector<PresentationDataValue> pdv =
153 CompositeMessageFactory::ConstructCEchoRQ(inConnection);
154 std::vector<PresentationDataValue>::iterator pdvItor;
155 std::vector<BasePDU*> outVector;
156 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
157 {
158 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
159 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
160 outVector.push_back(thePDataTFPDU);
161 }
162 return outVector;
163 }
164
CreateCMovePDU(const ULConnection & inConnection,const BaseRootQuery * inRootQuery)165 std::vector<BasePDU*> PDUFactory::CreateCMovePDU(const ULConnection&
166 inConnection, const BaseRootQuery* inRootQuery)
167 {
168 std::vector<PresentationDataValue> pdv =
169 CompositeMessageFactory::ConstructCMoveRQ(inConnection, inRootQuery );
170 std::vector<PresentationDataValue>::iterator pdvItor;
171 std::vector<BasePDU*> outVector;
172 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
173 {
174 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
175 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
176 outVector.push_back(thePDataTFPDU);
177 }
178 return outVector;
179 }
180
CreateCStoreRQPDU(const ULConnection & inConnection,const File & file,bool writeDataSet)181 std::vector<BasePDU*> PDUFactory::CreateCStoreRQPDU(const ULConnection& inConnection,
182 const File& file, bool writeDataSet /*= true*/ )
183 {
184 std::vector<PresentationDataValue> pdv =
185 CompositeMessageFactory::ConstructCStoreRQ(inConnection, file, writeDataSet );
186 std::vector<PresentationDataValue>::iterator pdvItor;
187 std::vector<BasePDU*> outVector;
188 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
189 {
190 PDataTFPDU* thePDataTFPDU = new PDataTFPDU;
191 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
192 outVector.push_back(thePDataTFPDU);
193 }
194 return outVector;
195 }
196
CreateCStoreRSPPDU(const DataSet * inDataSet,const BasePDU * inPDU)197 std::vector<BasePDU*> PDUFactory::CreateCStoreRSPPDU(const DataSet* inDataSet,
198 const BasePDU* inPDU)
199 {
200 std::vector<PresentationDataValue> pdv =
201 CompositeMessageFactory::ConstructCStoreRSP(inDataSet, inPDU );
202 std::vector<PresentationDataValue>::iterator pdvItor;
203 std::vector<BasePDU*> outVector;
204 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
205 {
206 PDataTFPDU* thePDataTFPDU = new PDataTFPDU;
207 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
208 outVector.push_back(thePDataTFPDU);
209 }
210 return outVector;
211 }
212
CreateCFindPDU(const ULConnection & inConnection,const BaseRootQuery * inRootQuery)213 std::vector<BasePDU*> PDUFactory::CreateCFindPDU(const ULConnection& inConnection,
214 const BaseRootQuery* inRootQuery)
215 {
216 //still have to build this!
217 std::vector<PresentationDataValue> pdv =
218 CompositeMessageFactory::ConstructCFindRQ(inConnection, inRootQuery );
219 std::vector<PresentationDataValue>::iterator pdvItor;
220 std::vector<BasePDU*> outVector;
221 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
222 {
223 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
224 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
225 outVector.push_back(thePDataTFPDU);
226 }
227 return outVector;
228
229
230 }
231
CreateNEventReportPDU(const ULConnection & inConnection,const BaseQuery * inQuery)232 std::vector<BasePDU*> PDUFactory::CreateNEventReportPDU (const ULConnection& inConnection, const BaseQuery *inQuery)
233 {
234 //still have to build this!
235 std::vector<PresentationDataValue> pdv =
236 NormalizedMessageFactory::ConstructNEventReport(inConnection, inQuery );
237 std::vector<PresentationDataValue>::iterator pdvItor;
238 std::vector<BasePDU*> outVector;
239 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
240 {
241 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
242 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
243 outVector.push_back(thePDataTFPDU);
244 }
245 return outVector;
246
247
248 }
CreateNGetPDU(const ULConnection & inConnection,const BaseQuery * inQuery)249 std::vector<BasePDU*> PDUFactory::CreateNGetPDU (const ULConnection& inConnection, const BaseQuery *inQuery)
250 {
251 //still have to build this!
252 std::vector<PresentationDataValue> pdv =
253 NormalizedMessageFactory::ConstructNGet(inConnection, inQuery );
254 std::vector<PresentationDataValue>::iterator pdvItor;
255 std::vector<BasePDU*> outVector;
256 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
257 {
258 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
259 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
260 outVector.push_back(thePDataTFPDU);
261 }
262 return outVector;
263
264
265 }
CreateNSetPDU(const ULConnection & inConnection,const BaseQuery * inQuery)266 std::vector<BasePDU*> PDUFactory::CreateNSetPDU (const ULConnection& inConnection, const BaseQuery *inQuery)
267 {
268 //still have to build this!
269 std::vector<PresentationDataValue> pdv =
270 NormalizedMessageFactory::ConstructNSet(inConnection, inQuery );
271 std::vector<PresentationDataValue>::iterator pdvItor;
272 std::vector<BasePDU*> outVector;
273 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
274 {
275 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
276 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
277 outVector.push_back(thePDataTFPDU);
278 }
279 return outVector;
280
281
282 }
CreateNActionPDU(const ULConnection & inConnection,const BaseQuery * inQuery)283 std::vector<BasePDU*> PDUFactory::CreateNActionPDU (const ULConnection& inConnection, const BaseQuery *inQuery)
284 {
285 //still have to build this!
286 std::vector<PresentationDataValue> pdv =
287 NormalizedMessageFactory::ConstructNAction(inConnection, inQuery );
288 std::vector<PresentationDataValue>::iterator pdvItor;
289 std::vector<BasePDU*> outVector;
290 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
291 {
292 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
293 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
294 outVector.push_back(thePDataTFPDU);
295 }
296 return outVector;
297
298
299 }
CreateNCreatePDU(const ULConnection & inConnection,const BaseQuery * inQuery)300 std::vector<BasePDU*> PDUFactory::CreateNCreatePDU (const ULConnection& inConnection, const BaseQuery *inQuery)
301 {
302 //still have to build this!
303 std::vector<PresentationDataValue> pdv =
304 NormalizedMessageFactory::ConstructNCreate(inConnection, inQuery );
305 std::vector<PresentationDataValue>::iterator pdvItor;
306 std::vector<BasePDU*> outVector;
307 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
308 {
309 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
310 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
311 outVector.push_back(thePDataTFPDU);
312 }
313 return outVector;
314
315
316 }
CreateNDeletePDU(const ULConnection & inConnection,const BaseQuery * inQuery)317 std::vector<BasePDU*> PDUFactory::CreateNDeletePDU (const ULConnection& inConnection, const BaseQuery *inQuery)
318 {
319 //still have to build this!
320 std::vector<PresentationDataValue> pdv =
321 NormalizedMessageFactory::ConstructNDelete(inConnection, inQuery );
322 std::vector<PresentationDataValue>::iterator pdvItor;
323 std::vector<BasePDU*> outVector;
324 for (pdvItor = pdv.begin(); pdvItor < pdv.end(); pdvItor++)
325 {
326 PDataTFPDU* thePDataTFPDU = new PDataTFPDU();
327 thePDataTFPDU->AddPresentationDataValue( *pdvItor );
328 outVector.push_back(thePDataTFPDU);
329 }
330 return outVector;
331
332
333 }
334
335
336 //given data pdus, produce the presentation data values stored within.
337 //all operations have these as the payload of the data sending operation
338 //however, echo does not have a dataset in the pdv.
GetPDVs(const std::vector<BasePDU * > & inDataPDUs)339 std::vector<PresentationDataValue> PDUFactory::GetPDVs(const std::vector<BasePDU*> & inDataPDUs)
340 {
341 std::vector<BasePDU*>::const_iterator itor;
342 std::vector<PresentationDataValue> outPDVs;
343 for (itor = inDataPDUs.begin(); itor < inDataPDUs.end(); itor++)
344 {
345 PDataTFPDU* thePDataTFPDU = dynamic_cast<PDataTFPDU*>(*itor);
346 if (thePDataTFPDU == nullptr)
347 {
348 assert(0); //shouldn't really get here.
349 return outPDVs; //just stop now, no longer with data pdus.
350 }
351 size_t theNumPDVsinPDU = thePDataTFPDU->GetNumberOfPresentationDataValues();
352 for (size_t i = 0; i < theNumPDVsinPDU; i++)
353 {
354 outPDVs.push_back(thePDataTFPDU->GetPresentationDataValue(i));
355 }
356 }
357 return outPDVs;
358 }
359 } // end namespace network
360 } // end namespace gdcm
361