~ubuntu-branches/ubuntu/oneiric/ginkgocadx/oneiric

« back to all changes in this revision

Viewing changes to src/cadxcore/main/controllers/dcmtk/dicomstoreassociation.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-05-02 08:09:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110502080926-bql5wep49c7hg91t
Tags: upstream-2.4.1.1
ImportĀ upstreamĀ versionĀ 2.4.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  $Id: dicomstoreassociation.cpp 3784 2011-04-27 12:07:33Z tovar $
 
4
 *  Ginkgo CADx Project
 
5
 *
 
6
 *  Copyright 2008-10 MetaEmotion S.L. All rights reserved.
 
7
 *  http://ginkgo-cadx.com
 
8
 *
 
9
 *  This file is licensed under LGPL v3 license.
 
10
 *  See License.txt for details
 
11
 *
 
12
 *  Code adapted from OsiriX
 
13
 *
 
14
 */
 
15
#define LOGGER "C-STORE"
 
16
#include <api/icontroladorlog.h>
 
17
#include <main/controllers/controladorlog.h>
 
18
#include <api/icontextoestudio.h>
 
19
#include "helpers.h"
 
20
 
 
21
#ifdef verify
 
22
#define MACRO_QUE_ESTORBA verify
 
23
#undef verify
 
24
#endif
 
25
 
 
26
#include "dicomstoreassociation.h"
 
27
#include <api/idicommanager.h>
 
28
#include <api/internacionalizacion.h>
 
29
#include <api/iproxynotificadorprogreso.h>
 
30
#include <main/controllers/controladorpermisos.h>
 
31
#include <main/entorno.h>
 
32
#include <iostream>
 
33
 
 
34
#include <main/controllers/dcmtk/dicomservers.h>
 
35
 
 
36
#include <dcmtk/ofstd/ofstring.h>
 
37
#include <dcmtk/dcmnet/dimse.h>
 
38
#include <dcmtk/dcmnet/diutil.h>
 
39
#include <dcmtk/dcmdata/dcdatset.h>
 
40
#include <dcmtk/dcmdata/dcmetinf.h>
 
41
#include <dcmtk/dcmdata/dcfilefo.h>
 
42
//#include <dcmtk/dcmdata/dcdebug.h>
 
43
#include <dcmtk/dcmdata/dcuid.h>
 
44
#include <dcmtk/dcmdata/dcdict.h>
 
45
#include <dcmtk/dcmdata/dcdeftag.h>
 
46
//#include "cmdlnarg.h"
 
47
#include <dcmtk/ofstd/ofconapp.h>
 
48
#include <dcmtk/dcmdata/dcuid.h>     /* for dcmtk version name */
 
49
#include <dcmtk/dcmnet/dicom.h>     /* for DICOM_APPLICATION_REQUESTOR */
 
50
#include <dcmtk/dcmdata/dcostrmz.h>  /* for dcmZlibCompressionLevel */
 
51
#include <dcmtk/dcmnet/dcasccfg.h>  /* for class DcmAssociationConfiguration */
 
52
#include <dcmtk/dcmnet/dcasccff.h>  /* for class DcmAssociationConfigurationFile */
 
53
 
 
54
#include <dcmtk/dcmjpeg/djencode.h>  /* for dcmjpeg encoders */
 
55
#include <dcmtk/dcmjpeg/djdecode.h>  /* for dcmjpeg encoders */
 
56
#include <dcmtk/dcmdata/dcrledrg.h>  /* for DcmRLEDecoderRegistration */
 
57
#include <dcmtk/dcmdata/dcrleerg.h>  /* for DcmRLEEncoderRegistration */
 
58
#include <dcmtk/dcmjpeg/djrploss.h>
 
59
#include <dcmtk/dcmjpeg/djrplol.h>
 
60
#include <dcmtk/dcmdata/dcpixel.h>
 
61
#include <dcmtk/dcmdata/dcrlerp.h>
 
62
 
 
63
#include "tls/tls.h"
 
64
#include "tls/gtlslayer.h"
 
65
#include <dcmtk/dcmtls/tlstrans.h>
 
66
 
 
67
#include "helpercompresion.h"
 
68
 
 
69
#ifdef MACRO_QUE_ESTORBA
 
70
#define verify MACRO_QUE_ESTORBA
 
71
#endif
 
72
 
 
73
#include <wx/filename.h>
 
74
#include <sstream>
 
75
 
 
76
/////////////////////-------------------------DEFINES--------------------/////////////////
 
77
 
 
78
namespace GIL {
 
79
        namespace DICOM {
 
80
 
 
81
                /* default application titles */
 
82
#define APPLICATIONTITLE        "GINKGO"
 
83
#define PEERAPPLICATIONTITLE    "DCM4CHEE"
 
84
 
 
85
                static OFBool opt_verbose = OFTrue;
 
86
                static OFBool opt_showPresentationContexts = OFTrue;
 
87
                static OFBool opt_debug = OFTrue;
 
88
                static OFBool opt_abortAssociation = OFFalse;
 
89
                static OFCmdUnsignedInt opt_maxReceivePDULength = ASC_DEFAULTMAXPDU;
 
90
                //static OFCmdUnsignedInt opt_maxSendPDULength = 0;
 
91
                static E_TransferSyntax opt_networkTransferSyntax = EXS_LittleEndianExplicit;
 
92
 
 
93
                //static OFBool opt_haltOnUnsuccessfulStore = OFTrue;
 
94
                static OFBool opt_haltOnUnsuccessfulStore = OFFalse;
 
95
                static OFBool unsuccessfulStoreEncountered = OFFalse;
 
96
                static std::string errorEncontrado;
 
97
                int lastStatusCode = STATUS_Success;
 
98
 
 
99
                static OFBool opt_proposeOnlyRequiredPresentationContexts = OFFalse;
 
100
                static OFBool opt_combineProposedTransferSyntaxes = OFFalse;
 
101
 
 
102
                static OFCmdUnsignedInt opt_repeatCount = 1;
 
103
                static OFCmdUnsignedInt opt_inventPatientCount = 25;
 
104
                static OFCmdUnsignedInt opt_inventStudyCount = 50;
 
105
                static OFCmdUnsignedInt opt_inventSeriesCount = 100;
 
106
                static OFBool opt_inventSOPInstanceInformation = OFFalse;
 
107
                static OFBool opt_correctUIDPadding = OFFalse;
 
108
                static OFString patientNamePrefix("OFFIS^TEST_PN_");   // PatientName is PN (maximum 16 chars)
 
109
                static OFString patientIDPrefix("PID_"); // PatientID is LO (maximum 64 chars)
 
110
                static OFString studyIDPrefix("SID_");   // StudyID is SH (maximum 16 chars)
 
111
                static OFString accessionNumberPrefix;  // AccessionNumber is SH (maximum 16 chars)
 
112
                //static OFBool opt_secureConnection = OFFalse; /* default: no secure connection */
 
113
                //static const char *opt_configFile = NULL;
 
114
                //static const char *opt_profileName = NULL;
 
115
                T_DIMSE_BlockingMode opt_blockMode = DIMSE_NONBLOCKING;
 
116
                int opt_dimse_timeout = 0;
 
117
                int opt_acse_timeout = 30;
 
118
                int opt_Quality = 100;
 
119
 
 
120
                //cancelacion
 
121
 
 
122
                typedef struct _StoreCallbackInfo {
 
123
                        T_ASC_Association* assoc;
 
124
                } GetCallbackInfo;
 
125
 
 
126
                //progreso
 
127
                static GNC::IProxyNotificadorProgreso* m_pNotificadorProgreso = NULL;
 
128
                static std::string m_mensaje("");
 
129
                typedef struct TMedida{
 
130
                        time_t m_instante;
 
131
                        int bytesDescargados;
 
132
                        float oldTasa;
 
133
                        TMedida() {
 
134
                                m_instante = time(NULL);
 
135
                                bytesDescargados = 0;
 
136
                                oldTasa = 0.0f;
 
137
                        }
 
138
                } TMedida;
 
139
                static TMedida m_medida;
 
140
 
 
141
                float TasaTransferencia(int bytesDescargados)
 
142
                {
 
143
                        time_t nuevoInstante = time(NULL);
 
144
                        const double tiempo = difftime(nuevoInstante,m_medida.m_instante);
 
145
                        if(tiempo>0.15f){
 
146
                                if(bytesDescargados > m_medida.bytesDescargados) {
 
147
                                        const double bytesRecibidosPeriodo = bytesDescargados - m_medida.bytesDescargados;
 
148
                                        m_medida.oldTasa = ( ((float)bytesRecibidosPeriodo/1024.0f)/tiempo );
 
149
                                        m_medida.bytesDescargados = bytesDescargados;
 
150
                                        m_medida.m_instante = nuevoInstante;
 
151
                                }
 
152
                        }
 
153
                        return m_medida.oldTasa;
 
154
                }
 
155
 
 
156
                void ResetearMedida(bool clearTasa = false) {
 
157
                        m_medida.bytesDescargados =-1;
 
158
                        m_medida.m_instante = time(NULL);
 
159
                        if(clearTasa) {
 
160
                                m_medida.oldTasa=0.0f;
 
161
                        }
 
162
                }
 
163
 
 
164
                static void errmsg(const std::string& mensaje, bool parar)
 
165
                {
 
166
                        LOG_ERROR(LOGGER,mensaje);
 
167
                        if(parar) {
 
168
                                throw GIL::DICOM::PACSException(mensaje);
 
169
                        }
 
170
                }
 
171
 
 
172
                /*
 
173
                 static void
 
174
                 errmsg(const OFString& message, bool parar)
 
175
                 {
 
176
                 std::string mensaje(message.c_str());
 
177
                 errmsg(mensaje,parar);
 
178
                 }
 
179
                 */
 
180
 
 
181
                static OFBool isaListMember(OFList<OFString>& lst, OFString& s)
 
182
                {
 
183
                        OFListIterator(OFString) cur = lst.begin();
 
184
                        OFListIterator(OFString) end = lst.end();
 
185
 
 
186
                        OFBool found = OFFalse;
 
187
 
 
188
                        while (cur != end && !found) {
 
189
 
 
190
                                found = (s == *cur);
 
191
 
 
192
                                ++cur;
 
193
                        }
 
194
 
 
195
                        return found;
 
196
                }
 
197
 
 
198
                static OFCondition addPresentationContext(T_ASC_Parameters *params,
 
199
                                                           int presentationContextId, const OFString& abstractSyntax,
 
200
                                                           const OFString& transferSyntax,
 
201
                                                           T_ASC_SC_ROLE proposedRole = ASC_SC_ROLE_DEFAULT)
 
202
                {
 
203
                        const char* c_p = transferSyntax.c_str();
 
204
                        OFCondition cond = ASC_addPresentationContext(params, presentationContextId,
 
205
                                                                                                                  abstractSyntax.c_str(), &c_p, 1, proposedRole);
 
206
                        return cond;
 
207
                }
 
208
 
 
209
                static OFCondition addPresentationContext(T_ASC_Parameters *params,
 
210
                                                           int presentationContextId, const OFString& abstractSyntax,
 
211
                                                           const OFList<OFString>& transferSyntaxList,
 
212
                                                           T_ASC_SC_ROLE proposedRole = ASC_SC_ROLE_DEFAULT)
 
213
                {
 
214
                        // create an array of supported/possible transfer syntaxes
 
215
                        const char** transferSyntaxes = new const char*[transferSyntaxList.size()];
 
216
                        int transferSyntaxCount = 0;
 
217
                        OFListConstIterator(OFString) s_cur = transferSyntaxList.begin();
 
218
                        OFListConstIterator(OFString) s_end = transferSyntaxList.end();
 
219
                        while (s_cur != s_end) {
 
220
                                transferSyntaxes[transferSyntaxCount++] = (*s_cur).c_str();
 
221
                                ++s_cur;
 
222
                        }
 
223
 
 
224
                        OFCondition cond = ASC_addPresentationContext(params, presentationContextId,
 
225
                                                                                                                  abstractSyntax.c_str(), transferSyntaxes, transferSyntaxCount, proposedRole);
 
226
 
 
227
                        delete[] transferSyntaxes;
 
228
                        return cond;
 
229
                }
 
230
 
 
231
                static OFCondition addStoragePresentationContexts(T_ASC_Parameters *params, OFList<OFString>& sopClasses)
 
232
                {
 
233
                        /*
 
234
                         * Each SOP Class will be proposed in two presentation contexts (unless
 
235
                         * the opt_combineProposedTransferSyntaxes global variable is true).
 
236
                         * The command line specified a preferred transfer syntax to use.
 
237
                         * This prefered transfer syntax will be proposed in one
 
238
                         * presentation context and a set of alternative (fallback) transfer
 
239
                         * syntaxes will be proposed in a different presentation context.
 
240
                         *
 
241
                         * Generally, we prefer to use Explicitly encoded transfer syntaxes
 
242
                         * and if running on a Little Endian machine we prefer
 
243
                         * LittleEndianExplicitTransferSyntax to BigEndianTransferSyntax.
 
244
                         * Some SCP implementations will just select the first transfer
 
245
                         * syntax they support (this is not part of the standard) so
 
246
                         * organise the proposed transfer syntaxes to take advantage
 
247
                         * of such behaviour.
 
248
                         */
 
249
 
 
250
                        // Which transfer syntax was preferred on the command line
 
251
                        OFString preferredTransferSyntax;
 
252
                        if (opt_networkTransferSyntax == EXS_Unknown) {
 
253
                                /* gLocalByteOrder is defined in dcxfer.h */
 
254
                                if (gLocalByteOrder == EBO_LittleEndian) {
 
255
                                        /* we are on a little endian machine */
 
256
                                        preferredTransferSyntax = UID_LittleEndianExplicitTransferSyntax;
 
257
                                } else {
 
258
                                        /* we are on a big endian machine */
 
259
                                        preferredTransferSyntax = UID_BigEndianExplicitTransferSyntax;
 
260
                                }
 
261
                        } else {
 
262
                                DcmXfer xfer(opt_networkTransferSyntax);
 
263
                                preferredTransferSyntax = xfer.getXferID();
 
264
                        }
 
265
 
 
266
                        OFListIterator(OFString) s_cur;
 
267
                        OFListIterator(OFString) s_end;
 
268
 
 
269
 
 
270
                        OFList<OFString> fallbackSyntaxes;
 
271
                        fallbackSyntaxes.push_back(UID_LittleEndianExplicitTransferSyntax);
 
272
                        fallbackSyntaxes.push_back(UID_BigEndianExplicitTransferSyntax);
 
273
                        fallbackSyntaxes.push_back(UID_LittleEndianImplicitTransferSyntax);
 
274
                        // Remove the preferred syntax from the fallback list
 
275
                        fallbackSyntaxes.remove(preferredTransferSyntax);
 
276
                        // If little endian implicit is preferred then we don't need any fallback syntaxes
 
277
                        // because it is the default transfer syntax and all applications must support it.
 
278
                        if (opt_networkTransferSyntax == EXS_LittleEndianImplicit) {
 
279
                                fallbackSyntaxes.clear();
 
280
                        }
 
281
 
 
282
                        // created a list of transfer syntaxes combined from the preferred and fallback syntaxes
 
283
                        OFList<OFString> combinedSyntaxes;
 
284
                        s_cur = fallbackSyntaxes.begin();
 
285
                        s_end = fallbackSyntaxes.end();
 
286
                        combinedSyntaxes.push_back(preferredTransferSyntax);
 
287
                        while (s_cur != s_end)
 
288
                        {
 
289
                                if (!isaListMember(combinedSyntaxes, *s_cur)) combinedSyntaxes.push_back(*s_cur);
 
290
                                ++s_cur;
 
291
                        }
 
292
 
 
293
                        if (!opt_proposeOnlyRequiredPresentationContexts) {
 
294
                                // add the (short list of) known storage sop classes to the list
 
295
                                // the array of Storage SOP Class UIDs comes from dcuid.h
 
296
                                
 
297
                                //FIXME: Ć‘APA HECHA PARA QUE PUEDA SUBIR VIDEOS(EL -1 Y EL PUSH DE DESPUES)
 
298
                                for (int i=0; i<numberOfDcmShortSCUStorageSOPClassUIDs-1; i++) {
 
299
                                        sopClasses.push_back(dcmShortSCUStorageSOPClassUIDs[i]);
 
300
                                }
 
301
                                //      UID_VideoPhotographicImageStorage
 
302
                                sopClasses.push_back("1.2.840.10008.5.1.4.1.1.77.1.4.1");
 
303
                        }
 
304
 
 
305
                        // thin out the sop classes to remove any duplicates.
 
306
                        OFList<OFString> sops;
 
307
                        s_cur = sopClasses.begin();
 
308
                        s_end = sopClasses.end();
 
309
                        while (s_cur != s_end) {
 
310
                                if (!isaListMember(sops, *s_cur)) {
 
311
                                        sops.push_back(*s_cur);
 
312
                                }
 
313
                                ++s_cur;
 
314
                        }
 
315
 
 
316
                        // add a presentations context for each sop class / transfer syntax pair
 
317
                        OFCondition cond = EC_Normal;
 
318
                        int pid = 1; // presentation context id
 
319
                        s_cur = sops.begin();
 
320
                        s_end = sops.end();
 
321
                        while (s_cur != s_end && cond.good()) {
 
322
 
 
323
                                if (pid > 255) {
 
324
                                        //errmsg("Demasiados contextos de presentacion");
 
325
                                        return ASC_BADPRESENTATIONCONTEXTID;
 
326
                                }
 
327
 
 
328
                                if (opt_combineProposedTransferSyntaxes) {
 
329
                                        cond = addPresentationContext(params, pid, *s_cur, combinedSyntaxes);
 
330
                                        pid += 2;   /* only odd presentation context id's */
 
331
                                } else {
 
332
 
 
333
                                        // sop class with preferred transfer syntax
 
334
                                        cond = addPresentationContext(params, pid, *s_cur, preferredTransferSyntax);
 
335
                                        pid += 2;   /* only odd presentation context id's */
 
336
 
 
337
                                        if (fallbackSyntaxes.size() > 0) {
 
338
                                                if (pid > 255) {
 
339
                                                        //errmsg("Demasiados contextos de presentacion");
 
340
                                                        return ASC_BADPRESENTATIONCONTEXTID;
 
341
                                                }
 
342
 
 
343
                                                // sop class with fallback transfer syntax
 
344
                                                cond = addPresentationContext(params, pid, *s_cur, fallbackSyntaxes);
 
345
                                                pid += 2;       /* only odd presentation context id's */
 
346
                                        }
 
347
                                }
 
348
                                ++s_cur;
 
349
                        }
 
350
 
 
351
                        return cond;
 
352
                }
 
353
 
 
354
                static int secondsSince1970()
 
355
                {
 
356
                        time_t t = time(NULL);
 
357
                        return (int)t;
 
358
                }
 
359
 
 
360
                static OFString intToString(int i)
 
361
                {
 
362
                        char numbuf[32];
 
363
                        sprintf(numbuf, "%d", i);
 
364
                        return numbuf;
 
365
                }
 
366
 
 
367
                static OFString makeUID(OFString basePrefix, int counter)
 
368
                {
 
369
                        OFString prefix = basePrefix + "." + intToString(counter);
 
370
                        char uidbuf[65];
 
371
                        OFString uid = dcmGenerateUniqueIdentifier(uidbuf, prefix.c_str());
 
372
                        return uid;
 
373
                }
 
374
 
 
375
                static OFBool updateStringAttributeValue(DcmItem* dataset, const DcmTagKey& key, OFString& value)
 
376
                {
 
377
                        DcmStack stack;
 
378
                        DcmTag tag(key);
 
379
 
 
380
                        OFCondition cond = EC_Normal;
 
381
                        cond = dataset->search(key, stack, ESM_fromHere, OFFalse);
 
382
                        if (cond != EC_Normal) {
 
383
                                LOG_DEBUG(LOGGER,"error: updateStringAttributeValue: cannot find: " << tag.getTagName() << " " << key << ": "<< cond.text());
 
384
                                return OFFalse;
 
385
                        }
 
386
 
 
387
                        DcmElement* elem = (DcmElement*) stack.top();
 
388
 
 
389
                        DcmVR vr(elem->ident());
 
390
                        if (elem->getLength() > vr.getMaxValueLength()) {
 
391
                                LOG_DEBUG(LOGGER,"error: updateStringAttributeValue: INTERNAL ERROR: " << tag.getTagName()<< " " << key << ": value too large (max "<< vr.getMaxValueLength() << ") for " << vr.getVRName() << " value: " << value );
 
392
                                return OFFalse;
 
393
                        }
 
394
 
 
395
                        cond = elem->putOFStringArray(value);
 
396
                        if (cond != EC_Normal) {
 
397
                                LOG_DEBUG(LOGGER, "error: updateStringAttributeValue: cannot put string in attribute: " << tag.getTagName()<< " " << key << ": "<< cond.text());
 
398
                                return OFFalse;
 
399
                        }
 
400
 
 
401
                        return OFTrue;
 
402
                }
 
403
 
 
404
                static void replaceSOPInstanceInformation(DcmDataset* dataset)
 
405
                {
 
406
                        static OFCmdUnsignedInt patientCounter = 0;
 
407
                        static OFCmdUnsignedInt studyCounter = 0;
 
408
                        static OFCmdUnsignedInt seriesCounter = 0;
 
409
                        static OFCmdUnsignedInt imageCounter = 0;
 
410
                        static OFString seriesInstanceUID;
 
411
                        static OFString seriesNumber;
 
412
                        static OFString studyInstanceUID;
 
413
                        static OFString studyID;
 
414
                        static OFString accessionNumber;
 
415
                        static OFString patientID;
 
416
                        static OFString patientName;
 
417
 
 
418
                        if (seriesInstanceUID.length() == 0) seriesInstanceUID=makeUID(SITE_SERIES_UID_ROOT, (int)seriesCounter);
 
419
                        if (seriesNumber.length() == 0) seriesNumber = intToString((int)seriesCounter);
 
420
                        if (studyInstanceUID.length() == 0) studyInstanceUID = makeUID(SITE_STUDY_UID_ROOT, (int)studyCounter);
 
421
                        if (studyID.length() == 0) studyID = studyIDPrefix + intToString((int)secondsSince1970()) + intToString((int)studyCounter);
 
422
                        if (accessionNumber.length() == 0) accessionNumber = accessionNumberPrefix + intToString(secondsSince1970()) + intToString((int)studyCounter);
 
423
                        if (patientID.length() == 0) patientID = patientIDPrefix + intToString(secondsSince1970()) + intToString((int)patientCounter);
 
424
                        if (patientName.length() == 0) patientName = patientNamePrefix + intToString(secondsSince1970()) + intToString((int)patientCounter);
 
425
 
 
426
                        if (imageCounter >= opt_inventSeriesCount) {
 
427
                                imageCounter = 0;
 
428
                                seriesCounter++;
 
429
                                seriesInstanceUID = makeUID(SITE_SERIES_UID_ROOT, (int)seriesCounter);
 
430
                                seriesNumber = intToString((int)seriesCounter);
 
431
                        }
 
432
                        if (seriesCounter >= opt_inventStudyCount) {
 
433
                                seriesCounter = 0;
 
434
                                studyCounter++;
 
435
                                studyInstanceUID = makeUID(SITE_STUDY_UID_ROOT, (int)studyCounter);
 
436
                                studyID = studyIDPrefix + intToString(secondsSince1970()) + intToString((int)studyCounter);
 
437
                                accessionNumber = accessionNumberPrefix + intToString(secondsSince1970()) + intToString((int)studyCounter);
 
438
                        }
 
439
                        if (studyCounter >= opt_inventPatientCount) {
 
440
                                // we create as many patients as necessary */
 
441
                                studyCounter = 0;
 
442
                                patientCounter++;
 
443
                                patientID = patientIDPrefix + intToString(secondsSince1970()) + intToString((int)patientCounter);
 
444
                                patientName = patientNamePrefix + intToString(secondsSince1970()) + intToString((int)patientCounter);
 
445
                        }
 
446
 
 
447
                        OFString sopInstanceUID = makeUID(SITE_INSTANCE_UID_ROOT, (int)imageCounter);
 
448
                        OFString imageNumber = intToString((int)imageCounter);
 
449
 
 
450
                        if (opt_debug) {
 
451
                                LOG_DEBUG(LOGGER, "Inventing Identifying Information (" <<
 
452
                                                  "pa" << patientCounter << ", st" << studyCounter <<
 
453
                                                  ", se" << seriesCounter << ", im" << imageCounter << "): " << std::endl
 
454
                                                  << "  PatientName=" << patientName << std::endl
 
455
                                                  << "  PatientID=" << patientID << std::endl
 
456
                                                  << "  StudyInstanceUID=" << studyInstanceUID << std::endl
 
457
                                                  << "  StudyID=" << studyID << std::endl
 
458
                                                  << "  SeriesInstanceUID=" << seriesInstanceUID << std::endl
 
459
                                                  << "  SeriesNumber=" << seriesNumber << std::endl
 
460
                                                  << "  SOPInstanceUID=" << sopInstanceUID << std::endl
 
461
                                                  << "  ImageNumber=" << imageNumber << std::endl);
 
462
                        }
 
463
 
 
464
                        updateStringAttributeValue(dataset, DCM_PatientName, patientName);
 
465
                        updateStringAttributeValue(dataset, DCM_PatientID, patientID);
 
466
                        updateStringAttributeValue(dataset, DCM_StudyInstanceUID, studyInstanceUID);
 
467
                        updateStringAttributeValue(dataset, DCM_StudyID, studyID);
 
468
                        updateStringAttributeValue(dataset, DCM_SeriesInstanceUID, seriesInstanceUID);
 
469
                        updateStringAttributeValue(dataset, DCM_SeriesNumber, seriesNumber);
 
470
                        updateStringAttributeValue(dataset, DCM_SOPInstanceUID, sopInstanceUID);
 
471
                        updateStringAttributeValue(dataset, DCM_InstanceNumber, imageNumber);
 
472
 
 
473
                        imageCounter++;
 
474
                }
 
475
 
 
476
                // ConversiĆ³n de transferencias
 
477
                static OFBool decompressFile(DcmFileFormat fileformat, const char * fname, const char *outfname)
 
478
                {
 
479
                        OFBool status = true;
 
480
                        OFCondition cond;
 
481
                        DcmXfer filexfer(fileformat.getDataset()->getOriginalXfer());
 
482
 
 
483
                        if (filexfer.getXfer() == EXS_JPEG2000LosslessOnly || filexfer.getXfer() == EXS_JPEG2000)
 
484
                        {
 
485
                                status = DecompressJPEG2000(fname, outfname);
 
486
                                LOG_WARN(LOGGER,"Se ha descomprimido desde JPEG2000, podrĆ­an perderse algunos tags");
 
487
                        }
 
488
                        else {
 
489
 
 
490
                                DcmDataset *dataset = fileformat.getDataset();
 
491
 
 
492
                                // decompress data set if compressed
 
493
                                dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL);
 
494
 
 
495
                                // check if everything went well
 
496
                                if (dataset->canWriteXfer(EXS_LittleEndianExplicit))
 
497
                                {
 
498
                                        fileformat.loadAllDataIntoMemory();
 
499
                                        unlink( outfname);
 
500
                                        cond = fileformat.saveFile( outfname, EXS_LittleEndianExplicit);
 
501
                                        status =  (cond.good()) ? true : false;
 
502
                                }
 
503
                                else
 
504
                                        status = false;
 
505
                        }
 
506
 
 
507
 
 
508
                        return status;
 
509
                }
 
510
 
 
511
                static OFBool compressFile(DcmFileFormat fileformat, const char * fname, const char *outfname)
 
512
                {
 
513
                        OFCondition cond;
 
514
                        OFBool status = true;
 
515
                        DcmXfer filexfer(fileformat.getDataset()->getOriginalXfer());
 
516
 
 
517
 
 
518
                        if (opt_networkTransferSyntax == EXS_JPEG2000)
 
519
                        {
 
520
                                status = CompressJPEG2000(fname, outfname);
 
521
                                LOG_WARN(LOGGER,"Se ha comprimido a JPEG2000, podrĆ­an perderse algunos tags");
 
522
                        }
 
523
                        else if  (opt_networkTransferSyntax == EXS_JPEG2000LosslessOnly)
 
524
                        {
 
525
                                status = CompressJPEG2000(fname, outfname);
 
526
                                LOG_WARN(LOGGER,"Se ha comprimido a JPEG2000, podrĆ­an perderse algunos tags");
 
527
                        }
 
528
                        else
 
529
                        {
 
530
                                DcmDataset *dataset = fileformat.getDataset();
 
531
                                DcmItem *metaInfo = fileformat.getMetaInfo();
 
532
                                DcmRepresentationParameter *params;
 
533
                                DJ_RPLossy lossyParams(opt_Quality);
 
534
                                DcmRLERepresentationParameter rleParams;
 
535
                                DJ_RPLossless losslessParams; // codec parameters, we use the defaults
 
536
                                if (opt_networkTransferSyntax == EXS_JPEGProcess14SV1TransferSyntax)
 
537
                                        params = &losslessParams;
 
538
                                else if (opt_networkTransferSyntax == EXS_JPEGProcess2_4TransferSyntax)
 
539
                                        params = &lossyParams;
 
540
                                else if (opt_networkTransferSyntax == EXS_RLELossless)
 
541
                                        params = &rleParams;
 
542
                                else
 
543
                                        params = &losslessParams;
 
544
 
 
545
 
 
546
                                // this causes the lossless JPEG version of the dataset to be created
 
547
                                dataset->chooseRepresentation(opt_networkTransferSyntax, params);
 
548
 
 
549
                                // check if everything went well
 
550
                                if (dataset->canWriteXfer(opt_networkTransferSyntax))
 
551
                                {
 
552
                                        // force the meta-header UIDs to be re-generated when storing the file
 
553
                                        // since the UIDs in the data set may have changed
 
554
                                        delete metaInfo->remove(DCM_MediaStorageSOPClassUID);
 
555
                                        delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID);
 
556
 
 
557
                                        // store in lossless JPEG format
 
558
 
 
559
                                        fileformat.loadAllDataIntoMemory();
 
560
 
 
561
                                        unlink( outfname);
 
562
 
 
563
                                        cond = fileformat.saveFile( outfname, opt_networkTransferSyntax);
 
564
                                        status =  (cond.good()) ? true : false;
 
565
                                }
 
566
                                else {
 
567
                                        status = false;
 
568
                                }
 
569
                        }
 
570
 
 
571
                        return status;
 
572
                }
 
573
 
 
574
 
 
575
                static long seed = 0;
 
576
 
 
577
 
 
578
                static OFCondition storeSCU(T_ASC_Association * assoc, const char *fname)
 
579
                /*
 
580
                 * This function will read all the information from the given file,
 
581
                 * figure out a corresponding presentation context which will be used
 
582
                 * to transmit the information over the network to the SCP, and it
 
583
                 * will finally initiate the transmission of all data to the SCP.
 
584
                 *
 
585
                 * Parameters:
 
586
                 *   assoc - [in] The association (network connection to another DICOM application).
 
587
                 *   fname - [in] Name of the file which shall be processed.
 
588
                 */
 
589
                {
 
590
                        DIC_US msgId = assoc->nextMsgID++;
 
591
                        T_ASC_PresentationContextID presId;
 
592
                        T_DIMSE_C_StoreRQ req;
 
593
                        T_DIMSE_C_StoreRSP rsp;
 
594
                        DIC_UI sopClass;
 
595
                        DIC_UI sopInstance;
 
596
                        std::ostringstream outfnameStringStream;
 
597
                        _StoreCallbackInfo storeCallbackData;
 
598
 
 
599
                        outfnameStringStream << GNC::Entorno::Instance()->GetGinkgoTempDir().c_str() << (char) wxFileName::GetPathSeparator(wxPATH_NATIVE) << seed++ << ".dcm";
 
600
 
 
601
                        std::string outfname = outfnameStringStream.str();
 
602
 
 
603
                        LOG_DEBUG(LOGGER, "tempfile: [" << outfname.c_str() << "]" );
 
604
 
 
605
                        //sprintf( outfname, "%s%ld.dcm",  "D:\\temp\\", seed++);
 
606
 
 
607
                        unsuccessfulStoreEncountered = OFTrue; // assumption
 
608
 
 
609
                        if (opt_debug) {
 
610
                                LOG_DEBUG(LOGGER, "--------------------------\nSending file: "<< fname);
 
611
                        }
 
612
 
 
613
                        /* read information from file. After the call to DcmFileFormat::loadFile(...) the information */
 
614
                        /* which is encapsulated in the file will be available through the DcmFileFormat object. */
 
615
                        /* In detail, it will be available through calls to DcmFileFormat::getMetaInfo() (for */
 
616
                        /* meta header information) and DcmFileFormat::getDataset() (for data set information). */
 
617
                        DcmFileFormat dcmff;
 
618
                        OFCondition cond = dcmff.loadFile(fname);
 
619
 
 
620
                        /* NO LO PONEMOS A FUEGO COMPRIMIMOS Y DESCOMPRIMIMOS
 
621
                         opt_networkTransferSyntax = dcmff.getDataset()->getOriginalXfer();
 
622
                         */
 
623
 
 
624
                        /* figure out if an error occured while the file was read*/
 
625
                        if (cond.bad()) {
 
626
                                LOG_DEBUG(LOGGER, "Bad DICOM file " << fname);
 
627
                                return cond;
 
628
                        }
 
629
 
 
630
                        /* if required, invent new SOP instance information for the current data set (user option) */
 
631
                        if (opt_inventSOPInstanceInformation) {
 
632
                                replaceSOPInstanceInformation(dcmff.getDataset());
 
633
                        }
 
634
 
 
635
                        /* figure out which SOP class and SOP instance is encapsulated in the file */
 
636
                        if (!DU_findSOPClassAndInstanceInDataSet(dcmff.getDataset(),
 
637
                                                                                                         sopClass, sopInstance, opt_correctUIDPadding)) {
 
638
                                LOG_DEBUG(LOGGER, "No SOP Class & Instance UIDs in file " << fname);
 
639
                                return DIMSE_BADDATA;
 
640
                        }
 
641
 
 
642
                        /* figure out which of the accepted presentation contexts should be used */
 
643
                        DcmXfer filexfer(dcmff.getDataset()->getOriginalXfer());
 
644
 
 
645
                        /* special case: if the file uses an unencapsulated transfer syntax (uncompressed
 
646
                         * or deflated explicit VR) and we prefer deflated explicit VR, then try
 
647
                         * to find a presentation context for deflated explicit VR first.
 
648
                         */
 
649
                        if (filexfer.isNotEncapsulated() &&
 
650
                                opt_networkTransferSyntax == EXS_DeflatedLittleEndianExplicit)
 
651
                        {
 
652
                                filexfer = EXS_DeflatedLittleEndianExplicit;
 
653
                        }
 
654
 
 
655
 
 
656
                        /************* do on the fly conversion here*********************/
 
657
 
 
658
                        //printf("on the fly conversion\n");
 
659
                        //we have a valid presentation ID,.Chaeck and see if file is consistent with it
 
660
                        DcmXfer preferredXfer(opt_networkTransferSyntax);
 
661
 
 
662
                        OFBool status = false;
 
663
                        presId = ASC_findAcceptedPresentationContextID(assoc, sopClass, preferredXfer.getXferID());
 
664
                        T_ASC_PresentationContext pc;
 
665
                        ASC_findAcceptedPresentationContext(assoc->params, presId, &pc);
 
666
                        DcmXfer proposedTransfer(pc.acceptedTransferSyntax);
 
667
 
 
668
                        status = true;
 
669
 
 
670
                        if (presId != 0)
 
671
                        {
 
672
                                if (filexfer.isNotEncapsulated() && proposedTransfer.isNotEncapsulated()) {
 
673
                                        // do nothing
 
674
                                        status = true;
 
675
                                }
 
676
                                else if (filexfer.isEncapsulated() && proposedTransfer.isNotEncapsulated()) {
 
677
                                        status = decompressFile(dcmff, fname, outfname.c_str());
 
678
                                }
 
679
                                else if (filexfer.isNotEncapsulated() && proposedTransfer.isEncapsulated()) {
 
680
                                        status = compressFile(dcmff, fname, outfname.c_str());
 
681
                                }
 
682
                                else if (filexfer.getXfer() != opt_networkTransferSyntax)
 
683
                                {
 
684
                                        // The file is already compressed, we will re-compress the file.....
 
685
                                        //E_TransferSyntax fileTS = filexfer.getXfer();
 
686
 
 
687
                                        if( (filexfer.getXfer() == EXS_JPEG2000LosslessOnly && preferredXfer.getXfer() == EXS_JPEG2000) ||
 
688
                                           (filexfer.getXfer() == EXS_JPEG2000 && preferredXfer.getXfer() == EXS_JPEG2000LosslessOnly))
 
689
                                        {
 
690
                                        }
 
691
                                        else {
 
692
                                                LOG_WARN(LOGGER,"Recompressing files that are already compressed, you should optimize your ts parameters to avoid this: presentation for syntax:" << dcmFindNameOfUID(filexfer.getXferID()) << " -> " << dcmFindNameOfUID(preferredXfer.getXferID()));
 
693
                                        }
 
694
                                        status = compressFile(dcmff, fname, outfname.c_str());
 
695
                                }
 
696
                        }
 
697
                        else
 
698
                                status = false;
 
699
 
 
700
 
 
701
                        if (status)
 
702
                        {
 
703
                                cond =  dcmff.loadFile( outfname.c_str());
 
704
                                filexfer = dcmff.getDataset()->getOriginalXfer();
 
705
 
 
706
                                /* figure out which SOP class and SOP instance is encapsulated in the file */
 
707
                                if (!DU_findSOPClassAndInstanceInDataSet(dcmff.getDataset(),
 
708
                                                                                                                 sopClass, sopInstance, opt_correctUIDPadding)) {
 
709
                                        LOG_DEBUG(LOGGER, "No SOP Class & Instance UIDs in file " << outfname);
 
710
                                        return DIMSE_BADDATA;
 
711
                                }
 
712
 
 
713
                                fname = outfname.c_str();
 
714
                        } else {
 
715
                                const char *modalityName = dcmSOPClassUIDToModality(sopClass);
 
716
                                if (!modalityName) modalityName = dcmFindNameOfUID(sopClass);
 
717
                                if (!modalityName) modalityName = "unknown SOP class";
 
718
                                LOG_DEBUG(LOGGER, "No presentation context for:  " << modalityName << "  "<< sopClass);
 
719
                                std::ostringstream ostr;
 
720
                                ostr << _Std("Ginkgo CADx is unable to compress from ") << filexfer.getXferName() << _Std(" to ") << proposedTransfer.getXferName();
 
721
                                errmsg(ostr.str(),true);
 
722
                                return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
 
723
                        }
 
724
 
 
725
                        if (filexfer.getXfer() != EXS_Unknown)
 
726
                                presId = ASC_findAcceptedPresentationContextID(assoc, sopClass, filexfer.getXferID());
 
727
                        else
 
728
                                presId = ASC_findAcceptedPresentationContextID(assoc, sopClass);
 
729
 
 
730
                        if (presId == 0) {
 
731
                                const char *modalityName = dcmSOPClassUIDToModality(sopClass);
 
732
                                if (!modalityName) modalityName = dcmFindNameOfUID(sopClass);
 
733
                                if (!modalityName) modalityName = "unknown SOP class";
 
734
                                LOG_DEBUG(LOGGER, "No presentation context for:  " << modalityName << "  "<< sopClass);
 
735
                                return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
 
736
                        }
 
737
 
 
738
                        /* if required, dump general information concerning transfer syntaxes */
 
739
                        if (opt_verbose) {
 
740
                                DcmXfer fileTransfer(dcmff.getDataset()->getOriginalXfer());
 
741
                                T_ASC_PresentationContext pc;
 
742
                                ASC_findAcceptedPresentationContext(assoc->params, presId, &pc);
 
743
                                DcmXfer netTransfer(pc.acceptedTransferSyntax);
 
744
                                LOG_DEBUG(LOGGER,"Transfer " << dcmFindNameOfUID(fileTransfer.getXferID()) << " -> " << dcmFindNameOfUID(netTransfer.getXferID()));
 
745
                        }
 
746
 
 
747
                        /* prepare the transmission of data */
 
748
                        bzero((char*)&req, sizeof(req));
 
749
                        req.MessageID = msgId;
 
750
                        strcpy(req.AffectedSOPClassUID, sopClass);
 
751
                        strcpy(req.AffectedSOPInstanceUID, sopInstance);
 
752
                        req.DataSetType = DIMSE_DATASET_PRESENT;
 
753
                        req.Priority = DIMSE_PRIORITY_LOW;
 
754
 
 
755
                        /* if required, dump some more general information */
 
756
                        if (opt_debug) {
 
757
                                LOG_DEBUG(LOGGER,"Store SCU RQ: MsgID (" <<msgId <<") "<< dcmSOPClassUIDToModality(sopClass));
 
758
                        }
 
759
 
 
760
                        /* finally conduct transmission of data */
 
761
                        {
 
762
                                storeCallbackData.assoc = assoc;
 
763
                                DcmDataset *statusDetail = NULL;
 
764
                                cond = DIMSE_storeUser(assoc, presId, &req,
 
765
                                                                           NULL, dcmff.getDataset(), GIL::DICOM::DicomStoreAssociation::progressCallback, &storeCallbackData,
 
766
                                                                           opt_blockMode, opt_dimse_timeout,
 
767
                                                                           &rsp, &statusDetail, NULL, OFStandard::getFileSize(fname));
 
768
 
 
769
                                /*
 
770
                                 * If store command completed normally, with a status
 
771
                                 * of success or some warning then the image was accepted.
 
772
                                 */
 
773
                                if (cond == EC_Normal && (rsp.DimseStatus == STATUS_Success || DICOM_WARNING_STATUS(rsp.DimseStatus))) {
 
774
                                        unsuccessfulStoreEncountered = OFFalse;
 
775
                                        /* dump status detail information if there is some */
 
776
                                        if (statusDetail != NULL) {
 
777
                                                LOG_DEBUG(LOGGER, "DIMSE_storeUser(): Estado: " << std::endl << DumpDataset(statusDetail));
 
778
                                                delete statusDetail;
 
779
                                        }
 
780
                                } else {
 
781
                                        //error!!!
 
782
                                        std::stringstream os;
 
783
                                        os<< "Error al enviar el archivo";
 
784
                                        if(statusDetail!=NULL)
 
785
                                                statusDetail->print(os);
 
786
                                        errorEncontrado = os.str();
 
787
                                        LOG_ERROR(LOGGER, errorEncontrado);
 
788
                                }
 
789
                                delete statusDetail;
 
790
                        }
 
791
 
 
792
                        /* remember the response's status for later transmissions of data */
 
793
                        lastStatusCode = rsp.DimseStatus;
 
794
 
 
795
                        /* dump some more general information */
 
796
                        if (cond == EC_Normal)
 
797
                        {
 
798
                                if (opt_debug) {
 
799
                                        LOG_DEBUG(LOGGER,"Fichero Subido Correctamente " << fname);
 
800
                                }
 
801
                        }
 
802
                        else
 
803
                        {
 
804
                                LOG_DEBUG(LOGGER,"Store failed: " << fname);
 
805
                                DimseCondition::dump(cond);
 
806
                        }
 
807
 
 
808
                        if( status)
 
809
                        {
 
810
                                // We created a temporary file. Delete it now.
 
811
 
 
812
                                unlink( outfname.c_str());
 
813
                        }
 
814
 
 
815
                        /* return */
 
816
                        return cond;
 
817
                }
 
818
 
 
819
 
 
820
                static OFCondition cstore(T_ASC_Association * assoc, const OFString& fname)
 
821
                /*
 
822
                 * This function will process the given file as often as is specified by opt_repeatCount.
 
823
                 * "Process" in this case means "read file, send C-STORE-RQ, receive C-STORE-RSP".
 
824
                 *
 
825
                 * Parameters:
 
826
                 *   assoc - [in] The association (network connection to another DICOM application).
 
827
                 *   fname - [in] Name of the file which shall be processed.
 
828
                 */
 
829
                {
 
830
                        OFCondition cond = EC_Normal;
 
831
 
 
832
                        /* opt_repeatCount specifies how many times a certain file shall be processed */
 
833
                        int n = (int)opt_repeatCount;
 
834
 
 
835
                        /* as long as no error occured and the counter does not equal 0 */
 
836
                        while ((cond.good()) && n-- && !(opt_haltOnUnsuccessfulStore && unsuccessfulStoreEncountered))
 
837
                        {
 
838
                                /* process file (read file, send C-STORE-RQ, receive C-STORE-RSP) */
 
839
                                cond = storeSCU(assoc, fname.c_str());
 
840
                        }
 
841
 
 
842
                        // we don't want to return an error code if --no-halt was specified.
 
843
                        if (! opt_haltOnUnsuccessfulStore)
 
844
                        {
 
845
                                cond = EC_Normal;
 
846
                        }
 
847
 
 
848
                        /* return result value */
 
849
                        return cond;
 
850
                }
 
851
 
 
852
                DicomStoreAssociation::DicomStoreAssociation()
 
853
                {
 
854
                        std::cout << std::endl;
 
855
                        m_TLS = false;
 
856
                        m_UseUserPass = false;
 
857
                        assoc = NULL;
 
858
                        net = NULL;
 
859
                }
 
860
 
 
861
                DicomStoreAssociation::~DicomStoreAssociation()
 
862
                {
 
863
#ifdef _WIN32
 
864
                        WSACleanup();
 
865
#endif
 
866
                        //no limpiamos no sea que los haya registrado otro que no seamos nosotros!!!
 
867
                        FreeMemory();
 
868
                }
 
869
 
 
870
                void DicomStoreAssociation::Store(ListaRutas listaFicheros, DicomServer* server, std::string nombreAETLocal,GNC::IProxyNotificadorProgreso* pNotificador, GIL::DICOM::TipoTransferSyntaxEnvio transferSyntax)
 
871
                {
 
872
                        if (listaFicheros.size() == 0)
 
873
                                return;
 
874
 
 
875
                        m_pNotificadorProgreso = pNotificador;
 
876
 
 
877
 
 
878
                        std::string nombreAETPar = server->AET;
 
879
                        opt_maxReceivePDULength = server->PDU;
 
880
                        std::string host = server->HostName;
 
881
                        unsigned int puerto = server->Port;
 
882
                        //TIMEOUT 15 SEGUNDOS
 
883
                        unsigned int dicomtimeout = 15;
 
884
                        bool _shouldAbort=false;
 
885
                        DcmFileFormat fileformat;
 
886
                        errorEncontrado ="";
 
887
 
 
888
                        E_TransferSyntax transferSyntaxFichero;
 
889
 
 
890
                        {
 
891
                                DcmFileFormat dcmff;
 
892
                                OFCondition cond;
 
893
                                cond = dcmff.loadFile(listaFicheros[0].c_str(),EXS_Unknown,EGL_noChange,DCM_TagInfoLength);
 
894
                                dcmff.loadAllDataIntoMemory();
 
895
                                if (cond.bad()) {
 
896
                                        errmsg(std::string("no se ha podido leer el dicom"),true);
 
897
                                } else {
 
898
                                        DcmElement* elemento;
 
899
                                        cond = dcmff.getDataset()->findAndGetElement(DcmTagKey(0x0010,0x0020),elemento);
 
900
                                        if(cond.bad()) {
 
901
                                                std::stringstream strStream;
 
902
                                                strStream << "Es necesario que este establecido el nombre y el ID del paciente";
 
903
                                                errmsg(strStream.str(),true);
 
904
                                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
905
                                        }
 
906
                                        cond = dcmff.getDataset()->findAndGetElement(DcmTagKey(0x0010,0x0010),elemento);
 
907
                                        if(cond.bad()) {
 
908
                                                std::stringstream strStream;
 
909
                                                strStream << "Es necesario que este establecido el nombre y el ID del paciente";
 
910
                                                errmsg(strStream.str(),true);
 
911
                                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
912
                                        }
 
913
                                }
 
914
                                transferSyntaxFichero = dcmff.getDataset()->getOriginalXfer();
 
915
                        }
 
916
 
 
917
 
 
918
                        //se pilla el nombre del estudio y dlpaciente... ahora se comienza
 
919
                        OFCondition cond;
 
920
                        const char *opt_peer = NULL;
 
921
                        OFCmdUnsignedInt opt_port = 104;
 
922
                        const char *opt_peerTitle = PEERAPPLICATIONTITLE;
 
923
                        const char *opt_ourTitle = APPLICATIONTITLE;
 
924
 
 
925
                        if(nombreAETPar.size()>0){
 
926
                                opt_peerTitle = nombreAETPar.c_str();
 
927
                        }
 
928
 
 
929
                        if(nombreAETLocal.size()>0){
 
930
                                opt_ourTitle = nombreAETLocal.c_str();
 
931
                        }
 
932
 
 
933
                        OFList<OFString> fileNameList;       // list of files to transfer to SCP
 
934
                        OFList<OFString> sopClassUIDList;    // the list of sop classes
 
935
                        OFList<OFString> sopInstanceUIDList; // the list of sop instances
 
936
 
 
937
                        T_ASC_Parameters *params;
 
938
                        DIC_NODENAME localHost;
 
939
                        DIC_NODENAME peerHost;
 
940
                        DcmAssociationConfiguration asccfg; // handler for association configuration profiles
 
941
 
 
942
                        opt_peer = host.c_str();
 
943
                        opt_port = puerto;
 
944
 
 
945
                        //verbose option set to true for now
 
946
                        opt_showPresentationContexts = OFFalse;
 
947
 
 
948
                        //debug code off for now
 
949
                        opt_debug = GNC::GCS::ControladorLog::Instance()->GetActiveLogLevel() == GNC::GCS::ControladorLog::DebugLog;
 
950
 
 
951
                        switch (transferSyntax) {
 
952
                                case SendExplicitLittleEndian:
 
953
                                        opt_networkTransferSyntax = EXS_LittleEndianExplicit;
 
954
                                        break;
 
955
                                case SendJPEG2000Lossless:
 
956
                                        opt_networkTransferSyntax = EXS_JPEG2000LosslessOnly;
 
957
                                        opt_Quality = 0;
 
958
                                        break;
 
959
                                case SendJPEG2000Lossy10:
 
960
                                        opt_networkTransferSyntax = EXS_JPEG2000;
 
961
                                        opt_Quality = 1;
 
962
                                        break;
 
963
                                case SendJPEG2000Lossy20:
 
964
                                        opt_networkTransferSyntax = EXS_JPEG2000;
 
965
                                        opt_Quality = 2;
 
966
                                        break;
 
967
                                case SendJPEG2000Lossy50:
 
968
                                        opt_networkTransferSyntax = EXS_JPEG2000;
 
969
                                        opt_Quality = 3;
 
970
                                        break;
 
971
                                case SendJPEGLossless:
 
972
                                        opt_networkTransferSyntax = EXS_JPEGProcess14SV1TransferSyntax;
 
973
                                        break;
 
974
                                case SendJPEGLossy9:
 
975
                                        opt_networkTransferSyntax = EXS_JPEGProcess2_4TransferSyntax;
 
976
                                        opt_Quality = 90;
 
977
                                        break;
 
978
                                case SendJPEGLossy8:
 
979
                                        opt_networkTransferSyntax = EXS_JPEGProcess2_4TransferSyntax;
 
980
                                        opt_Quality = 80;
 
981
                                        break;
 
982
                                case SendJPEGLossy7:
 
983
                                        opt_networkTransferSyntax = EXS_JPEGProcess2_4TransferSyntax;
 
984
                                        opt_Quality = 70;
 
985
                                        break;
 
986
                                case SendImplicitLittleEndian:
 
987
                                        opt_networkTransferSyntax = EXS_LittleEndianImplicit;
 
988
                                        break;
 
989
                                        /*      case SendRLE:
 
990
                                         opt_networkTransferSyntax = EXS_RLELossless;
 
991
                                         break;
 
992
                                         case SendExplicitBigEndian:
 
993
                                         opt_networkTransferSyntax = EXS_BigEndianExplicit;
 
994
                                         break;
 
995
                                         case SendBZip:
 
996
                                         opt_networkTransferSyntax = EXS_DeflatedLittleEndianExplicit;
 
997
                                         break;*/
 
998
                                case SendDefault:
 
999
                                        opt_networkTransferSyntax = transferSyntaxFichero;
 
1000
                                        //FIXME esta Ć±apa es necesaria porque el pacs de IRE no acepta baseline
 
1001
                                        if (GNC::GCS::ControladorPermisos::Instance()->Get("core.pacs.limits","force_lossless")) {
 
1002
                                                if (opt_networkTransferSyntax == EXS_JPEGProcess1TransferSyntax)
 
1003
                                                {
 
1004
                                                        opt_networkTransferSyntax = EXS_JPEGProcess14SV1TransferSyntax;
 
1005
                                                }
 
1006
                                        }
 
1007
                                        //
 
1008
                                        break;
 
1009
                        }
 
1010
 
 
1011
                        opt_proposeOnlyRequiredPresentationContexts = OFFalse;
 
1012
 
 
1013
                        dcmEnableUnknownVRGeneration.set(OFTrue);
 
1014
                        dcmEnableUnlimitedTextVRGeneration.set(OFTrue);
 
1015
 
 
1016
                        //      enable-new-vr
 
1017
                        dcmEnableUnknownVRGeneration.set(OFTrue);
 
1018
                        dcmEnableUnlimitedTextVRGeneration.set(OFTrue);
 
1019
 
 
1020
                        //Timeout
 
1021
                        OFCmdSignedInt opt_timeout = dicomtimeout;
 
1022
                        dcmConnectionTimeout.set((Sint32) opt_timeout);
 
1023
 
 
1024
                        //acse-timeout
 
1025
                        opt_acse_timeout = OFstatic_cast(int, opt_timeout);
 
1026
 
 
1027
                        //dimse-timeout
 
1028
                        opt_dimse_timeout = OFstatic_cast(int, opt_timeout);
 
1029
                        opt_blockMode = DIMSE_NONBLOCKING;
 
1030
 
 
1031
 
 
1032
                        int paramCount = listaFicheros.size();
 
1033
                        const char *currentFilename = NULL;
 
1034
                        char sopClassUID[128];
 
1035
                        char sopInstanceUID[128];
 
1036
                        OFBool ignoreName;
 
1037
 
 
1038
                        for (int i=0; i < paramCount; i++)
 
1039
                        {
 
1040
                                ignoreName = OFFalse;
 
1041
                                currentFilename = listaFicheros[i].c_str();
 
1042
 
 
1043
                                if (access(currentFilename, R_OK) < 0)
 
1044
                                {
 
1045
                                        std::stringstream strStream;
 
1046
                                        strStream << "No se puede acceder al fichero: " << currentFilename;
 
1047
                                        errmsg(strStream.str(), opt_haltOnUnsuccessfulStore);
 
1048
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1049
                                }
 
1050
                                else
 
1051
                                {
 
1052
                                        if (opt_proposeOnlyRequiredPresentationContexts)
 
1053
                                        {
 
1054
                                                if (!DU_findSOPClassAndInstanceInFile(currentFilename, sopClassUID, sopInstanceUID))
 
1055
                                                {
 
1056
                                                        ignoreName = OFTrue;
 
1057
                                                        std::stringstream strStream;
 
1058
                                                        strStream << "SOP class (o instance) no establecido en fichero: " << currentFilename;
 
1059
                                                        errmsg(strStream.str(), opt_haltOnUnsuccessfulStore);
 
1060
                                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1061
                                                }
 
1062
                                                else if (!dcmIsaStorageSOPClassUID(sopClassUID))
 
1063
                                                {
 
1064
                                                        ignoreName = OFTrue;
 
1065
                                                        std::stringstream strStream;
 
1066
                                                        strStream << "Storage sop class desconocido en fichero: " << currentFilename << ": " << sopClassUID;
 
1067
                                                        errmsg(strStream.str(), opt_haltOnUnsuccessfulStore);
 
1068
                                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1069
                                                }
 
1070
                                                else
 
1071
                                                {
 
1072
                                                        sopClassUIDList.push_back(sopClassUID);
 
1073
                                                        sopInstanceUIDList.push_back(sopInstanceUID);
 
1074
                                                }
 
1075
                                        }
 
1076
                                        if (!ignoreName) fileNameList.push_back(currentFilename);
 
1077
                                }
 
1078
                        }
 
1079
 
 
1080
                        /* make sure data dictionary is loaded */
 
1081
                        if (!dcmDataDict.isDictionaryLoaded()) {
 
1082
                                LOG_WARN(LOGGER, "Warning: no data dictionary loaded, check environment variable");
 
1083
                        }
 
1084
 
 
1085
#ifdef _WIN32
 
1086
                        WORD wVersionRequested;
 
1087
                        WSADATA wsaData;
 
1088
 
 
1089
                        wVersionRequested = MAKEWORD(1, 1);
 
1090
 
 
1091
                        WSAStartup(wVersionRequested, &wsaData);
 
1092
#endif
 
1093
 
 
1094
                        /* initialize network, i.e. create an instance of T_ASC_Network*. */
 
1095
 
 
1096
                        cond = ASC_initializeNetwork(NET_REQUESTOR, puerto, opt_acse_timeout, &net);
 
1097
                        if (cond.bad())
 
1098
                        {
 
1099
                                DimseCondition::dump(cond);
 
1100
                                std::stringstream strStream;
 
1101
                                strStream << "DICOM Network Failure (storescu) ASC_initializeNetwork; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1102
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1103
                                errmsg(strStream.str(),true);
 
1104
                        }
 
1105
 
 
1106
                        GTLSTransportLayer *tLayer = NULL;
 
1107
 
 
1108
 
 
1109
                        if (IsSecure())
 
1110
                        {
 
1111
                                tLayer = new GTLSTransportLayer(DICOM_APPLICATION_REQUESTOR, NULL);
 
1112
                                if (tLayer == NULL)
 
1113
                                {
 
1114
                                        DimseCondition::dump(cond);
 
1115
                                        std::stringstream strStream;
 
1116
                                        strStream << "Unable to create TLS transport layer";
 
1117
                                        errmsg(strStream.str(),true);
 
1118
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1119
                                }
 
1120
                                tLayer->setCertificateFromString(GetCliCert());
 
1121
                                tLayer->setPrivateKeyFromString(GetCliKey());
 
1122
 
 
1123
                                if (! tLayer->checkPrivateKeyMatchesCertificate())
 
1124
                                {
 
1125
                                        std::stringstream strStream;
 
1126
                                        strStream << "private key and certificate do not match";
 
1127
                                        errmsg(strStream.str(),true);
 
1128
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1129
                                }
 
1130
 
 
1131
                                tLayer->addSystemTrustedCertificates();
 
1132
 
 
1133
                                if (GetValidate()) {
 
1134
                                        tLayer->setCertificateVerification(DCV_requireCertificate);
 
1135
                                }
 
1136
                                else {
 
1137
                                        tLayer->setCertificateVerification(DCV_ignoreCertificate);
 
1138
                                }
 
1139
                                /*
 
1140
                                 if (opt_dhparam && ! (tLayer->setTempDHParameters(opt_dhparam)))
 
1141
                                 {
 
1142
                                 LOG_WARN(assoc->ambitolog, "unable to load temporary DH parameters. Ignoring");
 
1143
                                 }
 
1144
                                 */
 
1145
 
 
1146
                                cond = ASC_setTransportLayer(net, tLayer, 0);
 
1147
                                if (cond.bad())
 
1148
                                {
 
1149
                                        LOG_ERROR("C-STORE", "Error al insertar capa de transporte segura: " << cond.text());
 
1150
                                }
 
1151
                        }
 
1152
 
 
1153
                        /* initialize asscociation parameters, i.e. create an instance of T_ASC_Parameters*. */
 
1154
                        cond = ASC_createAssociationParameters(&params, opt_maxReceivePDULength);
 
1155
                        DimseCondition::dump(cond);
 
1156
                        if (cond.bad())
 
1157
                        {
 
1158
                                DimseCondition::dump(cond);
 
1159
                                std::stringstream strStream;
 
1160
                                strStream << "DICOM Network Failure (storescu) ASC_createAssociationParameters; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1161
                                errmsg(strStream.str(),true);
 
1162
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1163
                        }
 
1164
 
 
1165
                        if (UseUserPass()) {
 
1166
                                cond = ASC_setIdentRQUserPassword(params, GetUser().c_str(), GetPass().c_str());
 
1167
                                DimseCondition::dump(cond);
 
1168
                        }
 
1169
                        
 
1170
                        if (cond.bad()) {
 
1171
                                std::stringstream strStream;
 
1172
                                strStream << "DICOM Network Failure (storescu) ASC_createAssociationParameters; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1173
                                errmsg(strStream.str(),true);
 
1174
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1175
                         }
 
1176
 
 
1177
                        /* sets this application's title and the called application's title in the params */
 
1178
                        /* structure. The default values to be set here are "STORESCU" and "ANY-SCP". */
 
1179
                        ASC_setAPTitles(params, opt_ourTitle, opt_peerTitle, NULL);
 
1180
 
 
1181
                        /* Set the transport layer type (type of network connection) in the params */
 
1182
                        /* strucutre. The default is an insecure connection; where OpenSSL is  */
 
1183
                        /* available the user is able to request an encrypted,secure connection. */
 
1184
                        cond = ASC_setTransportLayerType(params, IsSecure());
 
1185
                        if (cond.bad()) {
 
1186
                                DimseCondition::dump(cond);
 
1187
                                std::stringstream strStream;
 
1188
                                strStream << "DICOM Network Failure (storescu) ASC_setTransportLayerType; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1189
                                errmsg(strStream.str(),true);
 
1190
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1191
                        }
 
1192
 
 
1193
                        /* Figure out the presentation addresses and copy the */
 
1194
                        /* corresponding values into the association parameters.*/
 
1195
                        gethostname(localHost, sizeof(localHost) - 1);
 
1196
                        sprintf(peerHost, "%s:%d", opt_peer, (int)opt_port);
 
1197
                        //NSLog(@"peer host: %s", peerHost);
 
1198
                        cond = ASC_setPresentationAddresses(params, localHost, peerHost);
 
1199
                        if (cond.bad()) {
 
1200
                                DimseCondition::dump(cond);
 
1201
                                std::stringstream strStream;
 
1202
                                strStream << "DICOM Network Failure (storescu) ASC_setPresentationAddresses; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1203
                                errmsg(strStream.str(),true);
 
1204
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1205
                        }
 
1206
 
 
1207
                        /* Set the presentation contexts which will be negotiated */
 
1208
                        /* when the network connection will be established */
 
1209
                        cond = addStoragePresentationContexts(params, sopClassUIDList);
 
1210
                        if (cond.bad()) {
 
1211
                                DimseCondition::dump(cond);
 
1212
                                std::stringstream strStream;
 
1213
                                strStream << "DICOM Network Failure (storescu) addStoragePresentationContexts; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1214
                                errmsg(strStream.str(),true);
 
1215
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1216
                        }
 
1217
 
 
1218
 
 
1219
                        /* dump presentation contexts if required */
 
1220
                        if(opt_debug){
 
1221
                                std::stringstream strStream;
 
1222
                                strStream << "Request Parameters:\n";
 
1223
                                ASC_dumpParameters(params, strStream);
 
1224
                                LOG_DEBUG(LOGGER,strStream.str());
 
1225
                        }
 
1226
 
 
1227
                        /* create association, i.e. try to establish a network connection to another */
 
1228
                        /* DICOM application. This call creates an instance of T_ASC_Association*. */
 
1229
                        LOG_DEBUG(LOGGER,"Requesting Association");
 
1230
                        cond = ASC_requestAssociation(net, params, &assoc);
 
1231
                        if (cond.bad()) {
 
1232
                                if (cond == DUL_ASSOCIATIONREJECTED) {
 
1233
                                        T_ASC_RejectParameters rej;
 
1234
                                        ASC_getRejectParameters(params, &rej);
 
1235
                                        ASC_printRejectParameters(stderr, &rej);
 
1236
                                        DimseCondition::dump(cond);
 
1237
                                        std::stringstream strStream;
 
1238
                                        strStream << "DICOM Network Failure (storescu) ASC_requestAssociation[DUL_ASSOCIATIONREJECTED]; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1239
                                        errmsg(strStream.str(),true);
 
1240
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1241
                                } else {
 
1242
                                        DimseCondition::dump(cond);
 
1243
                                        std::stringstream strStream;
 
1244
                                        strStream << "DICOM Network Failure (storescu) ASC_requestAssociation[Unknown]; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1245
                                        errmsg(strStream.str(),true);
 
1246
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1247
                                }
 
1248
                        }
 
1249
 
 
1250
                        /* dump the connection parameters if in debug mode*/
 
1251
                        if(opt_debug)
 
1252
                        {
 
1253
                                std::stringstream strStream;
 
1254
                                strStream << "Connection Parameters:\n";
 
1255
                                ASC_dumpConnectionParameters(assoc, strStream);
 
1256
                                LOG_DEBUG(LOGGER,strStream.str());
 
1257
                        }
 
1258
 
 
1259
                        /* dump the presentation contexts which have been accepted/refused */
 
1260
                        if(opt_debug){
 
1261
                                std::stringstream strStream;
 
1262
                                strStream << "Association Parameters Negotiated:\n";
 
1263
                                ASC_dumpParameters(params, strStream);
 
1264
                                LOG_DEBUG(LOGGER,strStream.str());
 
1265
                        }
 
1266
 
 
1267
                        /* count the presentation contexts which have been accepted by the SCP */
 
1268
                        /* If there are none, finish the execution */
 
1269
                        if (ASC_countAcceptedPresentationContexts(params) == 0) {
 
1270
                                std::stringstream strStream;
 
1271
                                strStream << "DICOM Network Failure (storescu) Contextos de presentacion no aceptados";
 
1272
                                errmsg(strStream.str(),true);
 
1273
                                LOG_WARN("C-STORE", strStream.str().c_str());
 
1274
                        }
 
1275
 
 
1276
                        /* dump general information concerning the establishment of the network connection if required */
 
1277
                        if (opt_debug) {
 
1278
                                std::stringstream strStream;
 
1279
                                strStream << "Association Accepted (Max Send PDV: "<< assoc->sendPDVLength;
 
1280
                                LOG_DEBUG(LOGGER,strStream.str());
 
1281
                        }
 
1282
 
 
1283
                        /* do the real work, i.e. for all files which were specified in the */
 
1284
                        /* command line, transmit the encapsulated DICOM objects to the SCP. */
 
1285
                        cond = EC_Normal;
 
1286
                        OFListIterator(OFString) iter = fileNameList.begin();
 
1287
                        OFListIterator(OFString) enditer = fileNameList.end();
 
1288
 
 
1289
                        int _numberSent=0;
 
1290
                        //int _numberOfFiles =0;
 
1291
                        //int _numberErrors =0;
 
1292
                        OFString mensaje;
 
1293
 
 
1294
                        ResetearMedida(true);
 
1295
                        while ((iter != enditer) && (cond == EC_Normal) && !_shouldAbort) // compare with EC_Normal since DUL_PEERREQUESTEDRELEASE is also good()
 
1296
                        {
 
1297
                                wxString msg = wxString::Format(_("Uploading file %d of %d"),(_numberSent+1), listaFicheros.size());
 
1298
                                m_mensaje = std::string(msg.ToUTF8());
 
1299
                                pNotificador->NotificarProgreso(0.0f, m_mensaje);
 
1300
 
 
1301
                                cond = cstore(assoc, *iter);
 
1302
                                ++iter;
 
1303
                                if (!unsuccessfulStoreEncountered)
 
1304
                                        _numberSent++;
 
1305
                                else {
 
1306
                                        //error cerramos las conexiones...
 
1307
                                        break;
 
1308
                                }
 
1309
 
 
1310
                                //TODO CONFIGURACION MAXIMO NUMERO DFICHEROS Q SEPUEDE SUBIR, MAXIMO NUMERO DE ERRORES...
 
1311
                        }
 
1312
 
 
1313
 
 
1314
                        /* tear down association, i.e. terminate network connection to SCP */
 
1315
                        if (cond == EC_Normal)
 
1316
                        {
 
1317
                                if (opt_abortAssociation)
 
1318
                                {
 
1319
                                        cond = ASC_abortAssociation(assoc);
 
1320
                                        if (cond.bad())
 
1321
                                        {
 
1322
                                                LOG_DEBUG(LOGGER,"Abortando Asociacion: \n");
 
1323
                                                DimseCondition::dump(cond);
 
1324
                                                std::stringstream strStream;
 
1325
                                                strStream << "DICOM Network Failure (storescu) Association Abort Failed; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1326
                                                errmsg(strStream.str(),true);
 
1327
                                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1328
                                        }
 
1329
                                } else
 
1330
                                {
 
1331
                                        /* release association */
 
1332
                                        LOG_DEBUG(LOGGER,"Abortando Asociacion: \n");
 
1333
                                        cond = ASC_releaseAssociation(assoc);
 
1334
                                        if (cond.bad())
 
1335
                                        {
 
1336
                                                ASC_dropAssociation(assoc);
 
1337
                                                DimseCondition::dump(cond);
 
1338
                                                std::stringstream strStream;
 
1339
                                                strStream << "DICOM Network Failure (storescu) Association Abort Failed; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1340
                                                errmsg(strStream.str(),true);
 
1341
                                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1342
                                        }
 
1343
                                }
 
1344
                        }
 
1345
                        else if (cond == DUL_PEERREQUESTEDRELEASE)
 
1346
                        {
 
1347
                                LOG_DEBUG(LOGGER,"Abortando Asociacion [PEERREQUESTEDRELEASE]");
 
1348
 
 
1349
                                cond = ASC_abortAssociation(assoc);
 
1350
                                if (cond.bad())
 
1351
                                {
 
1352
                                        std::stringstream strStream;
 
1353
                                        strStream << "DICOM Network Failure (storescu) Association Abort Failed; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1354
                                        errmsg(strStream.str(),true);
 
1355
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1356
                                }
 
1357
                        }
 
1358
                        else if (cond == DUL_PEERABORTEDASSOCIATION)
 
1359
                        {
 
1360
                                std::stringstream strStream;
 
1361
                                strStream << "Fallo en la red DICOM (storescu) El servidor ha cerrado la conexion ";
 
1362
                                errmsg(strStream.str(),true);
 
1363
                                LOG_ERROR("C-STORE", strStream.str().c_str());
 
1364
                        }
 
1365
                        else
 
1366
                        {
 
1367
                                DimseCondition::dump(cond);
 
1368
                                LOG_DEBUG(LOGGER,"Abortando Asociacion");
 
1369
 
 
1370
                                cond = ASC_abortAssociation(assoc);
 
1371
                                if (cond.bad())
 
1372
                                {
 
1373
                                        DimseCondition::dump(cond);
 
1374
                                        std::stringstream strStream;
 
1375
                                        strStream << "DICOM Network Failure (storescu) Protocol Error: SCU Failed; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1376
                                        errmsg(strStream.str(),true);
 
1377
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1378
                                }
 
1379
                        }
 
1380
 
 
1381
                        if ( unsuccessfulStoreEncountered)
 
1382
                        {
 
1383
                                throw GIL::DICOM::PACSException(errorEncontrado);
 
1384
                        }
 
1385
                }
 
1386
 
 
1387
                void DicomStoreAssociation::FreeMemory()
 
1388
                {
 
1389
                        /* destroy the association, i.e. free memory of T_ASC_Association* structure. This */
 
1390
                        /* call is the counterpart of ASC_requestAssociation(...) which was called above. */
 
1391
                        if (assoc != NULL) {
 
1392
                                OFCondition cond = ASC_destroyAssociation(&assoc);
 
1393
                                if (cond.bad())
 
1394
                                {
 
1395
                                        DimseCondition::dump(cond);
 
1396
                                        std::stringstream strStream;
 
1397
                                        strStream << "DICOM Network Failure (storescu) Protocol Error: ASC_destroyAssociation; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1398
                                        errmsg(strStream.str(),true);
 
1399
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1400
                                }
 
1401
                        }
 
1402
                        /* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
 
1403
                        /* is the counterpart of ASC_initializeNetwork(...) which was called above. */
 
1404
 
 
1405
                        if (net!= NULL) {
 
1406
                                OFCondition cond = ASC_dropNetwork(&net);
 
1407
                                if (cond.bad())
 
1408
                                {
 
1409
                                        DimseCondition::dump(cond);
 
1410
                                        std::stringstream strStream;
 
1411
                                        strStream << "DICOM Network Failure (storescu) Protocol Error: ASC_dropNetwork; Modulo: "<< cond.module() << "; Code:"<< cond.code() << "; " << cond.text();
 
1412
                                        errmsg(strStream.str(),true);
 
1413
                                        LOG_ERROR("C-STORE", strStream.str().c_str());
 
1414
                                }
 
1415
                        }
 
1416
                }
 
1417
        }
 
1418
}
 
1419
 
 
1420
void GIL::DICOM::DicomStoreAssociation::progressCallback(void * callbackData,
 
1421
                                                                                                        T_DIMSE_StoreProgress *progress,
 
1422
                                                                                                        T_DIMSE_C_StoreRQ * /*req*/)
 
1423
{
 
1424
        _StoreCallbackInfo *cbdata = (_StoreCallbackInfo*) callbackData;
 
1425
 
 
1426
        if (progress->state == DIMSE_StoreProgressing) {
 
1427
                //si ha pasado medio segundo...
 
1428
                std::stringstream ostr;
 
1429
                ostr << m_mensaje;
 
1430
                ostr.setf(std::ios::floatfield, std::ios::fixed );
 
1431
                ostr.precision(2);
 
1432
                ostr << " a " << TasaTransferencia(progress->progressBytes) << " kb/s";
 
1433
                std::string msg(ostr.str());
 
1434
 
 
1435
                if(!m_pNotificadorProgreso->NotificarProgreso((float)progress->progressBytes/progress->totalBytes,msg))
 
1436
                {
 
1437
                        ASC_abortAssociation(cbdata->assoc);
 
1438
                }
 
1439
        }
 
1440
        if (progress->state == DIMSE_StoreEnd) {
 
1441
                ResetearMedida();
 
1442
        }
 
1443
}
 
1444