~ubuntu-branches/ubuntu/trusty/ginkgocadx/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2013-07-21 11:58:53 UTC
  • mfrom: (1.2.1) (7.1.6 experimental)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: package-import@ubuntu.com-20130721115853-0aii5ee76hxm8z1f
* New upstream release [July 2013]
  + new B-D: "libjsoncpp-dev".
  + new patch "unbundle-libjsoncpp.patch" to avoid building bundled
    "libjsoncpp-dev".
  + new patch "fix-wx.patch" to avoid FTBFS due to missing
    "-lwx_gtk2u_html-2.8".
* Removed unnecessary versioned Build-Depends.
* Removed obsolete lintian override.
* Reference get-orig-source implementation for orig.tar clean-up and
  DFSG-repackaging.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  
3
 
 *  $Id: dicommoveassociation.cpp 4811 2012-04-02 12:24:41Z carlos $
 
3
 *  $Id: dicommoveassociation.cpp $
4
4
 *  Ginkgo CADx Project
5
5
 *
6
 
 *  Copyright 2008-10 MetaEmotion S.L. All rights reserved.
 
6
 *  Copyright 2008-12 MetaEmotion S.L. All rights reserved.
7
7
 *  http://ginkgo-cadx.com
8
8
 *
9
9
 *  This file is licensed under LGPL v3 license.
14
14
 */
15
15
#define LOGGER "C-MOVE"
16
16
 
17
 
#include <api/icontroladorlog.h>
 
17
#include <api/controllers/icontroladorlog.h>
18
18
#include <main/controllers/controladorlog.h>
19
19
#include <api/dicom/imodelodicom.h>
20
20
#include <main/controllers/controladorpermisos.h>
21
21
#include <api/controllers/ipacscontroller.h>
22
22
#include <main/entorno.h>
23
23
 
24
 
#include <api/icontextoestudio.h>
25
 
#include <api/internacionalization/internacionalization.h>
 
24
#include <api/internationalization/internationalization.h>
26
25
 
27
26
#include "istorecallback.h"
28
27
 
44
43
#include "tls/gtlslayer.h"
45
44
#include <dcmtk/dcmtls/tlstrans.h>
46
45
 
47
 
std::string MoveAssociation::m_errorMessage = "";
 
46
MoveAssociation::MoveAssociation(const std::string& _ambitolog, IModeloDicom* pModelo) : FindAssociation(_ambitolog),
 
47
                m_maxReceivePDULength(ASC_DEFAULTMAXPDU),
 
48
                m_pModelo(pModelo),
 
49
                m_errorMessage("")
 
50
{
 
51
        m_abstractSyntax = UID_MOVEStudyRootQueryRetrieveInformationModel;
48
52
 
49
 
MoveAssociation::MoveAssociation(const std::string& _ambitolog, IModeloDicom* pModelo) : FindAssociation(_ambitolog) {
50
 
        m_abstractSyntax = (char*) UID_MOVEStudyRootQueryRetrieveInformationModel;
51
 
        m_maxReceivePDULength = ASC_DEFAULTMAXPDU;
52
 
        m_pHandler = NULL;
53
 
        m_pModelo = pModelo;
54
 
        m_numeroImagenes=0;
55
 
        m_mensaje="";
56
 
        m_errorMessage = "";
57
 
        m_bytesDescargados = 0;
58
53
}
59
54
 
60
55
MoveAssociation::~MoveAssociation() { }
84
79
        DcmDataset* rspIds = NULL;
85
80
        const char* sopClass;
86
81
        DcmDataset* statusDetail = NULL;
87
 
        MoveCallbackInfo callbackData;
88
82
 
89
83
        if (pdset == NULL) {
90
 
                LOG_ERROR(ambitolog, "Dataset nulo en moveSCU");
91
 
                return DIMSE_NULLKEY;
 
84
                return makeOFCondition(OFM_dcmnet, DIMSEC_BADDATA, OF_error, "NULL DIMSE Query");
92
85
        }
93
86
 
94
87
        //sopClass = m_abstractSyntaxMove;
101
94
                return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
102
95
        }
103
96
 
104
 
        callbackData.assoc = assoc;
105
 
        callbackData.presId = presId;
106
 
        callbackData.pCaller = this;
107
 
 
108
97
        req.MessageID = msgId;
109
98
        strcpy(req.AffectedSOPClassUID, sopClass);
110
99
        req.Priority = DIMSE_PRIORITY_HIGH;
111
100
        req.DataSetType = DIMSE_DATASET_PRESENT;
112
101
        strcpy(req.MoveDestination, m_ourAET.c_str());
113
102
 
114
 
        ResetearMedida(true);
115
 
        m_numeroImagenes=0;
116
103
        cond = DIMSE_moveUser(
117
104
                assoc,
118
105
                presId,
119
106
                &req,
120
107
                pdset,
121
 
                moveCallback,
122
 
                &callbackData,
 
108
                NULL,
 
109
                NULL,
123
110
                DIMSE_BLOCKING,
124
111
                0,
125
112
                GetNetwork()->GetDcmtkNet(),
126
 
                subOpCallback,
 
113
                NULL,
127
114
                this,
128
115
                &rsp, &statusDetail, &rspIds);
129
116
 
 
117
        if( rsp.DimseStatus != STATUS_Success && rsp.DimseStatus != STATUS_Pending) {
 
118
                std::ostringstream os;
 
119
                os << DU_cmoveStatusString(rsp.DimseStatus);
 
120
                if (statusDetail != NULL) {
 
121
                        OFString errorComment;
 
122
                        if (statusDetail->findAndGetOFString(DCM_ErrorComment, errorComment).good()) {
 
123
                                os << ". " << errorComment.c_str();
 
124
                        }
 
125
                }       
 
126
                m_errorMessage = os.str();
 
127
        }
 
128
 
130
129
        if (statusDetail != NULL) {
131
130
                LOG_DEBUG(ambitolog, "DIMSE_moveUser(): Estado: " << std::endl << DumpDataset(statusDetail));
132
131
                delete statusDetail;
136
135
                delete rspIds;
137
136
        }
138
137
 
139
 
        if(m_errorMessage != "")
140
 
        {
141
 
                throw GIL::DICOM::PACSException(m_errorMessage, "Acquisition");
142
 
        }
143
 
 
144
 
        return cond;
145
 
}
146
 
 
147
 
void MoveAssociation::moveCallback(void* /*callbackData*/, T_DIMSE_C_MoveRQ* /*request*/, int /*responseCount*/, T_DIMSE_C_MoveRSP* /*response*/)
148
 
{
149
 
}
150
 
 
151
 
void MoveAssociation::subOpCallback(void *pCaller, T_ASC_Network *aNet, T_ASC_Association **subAssoc) {
152
 
        MoveAssociation* caller = (MoveAssociation*) pCaller;
153
 
 
154
 
        if (caller->GetNetwork() == NULL) {
155
 
                return;
156
 
        }
157
 
 
158
 
        wxString msg = wxString::Format(_("Downloading file %d"), caller->m_numeroImagenes++);
159
 
        caller->m_mensaje = std::string(msg.ToUTF8());
160
 
        LOG_DEBUG(caller->ambitolog, caller->m_mensaje);
161
 
        caller->NotificarProgreso((float)caller->m_numeroImagenes/100,caller->m_mensaje);
162
 
 
163
 
        if (*subAssoc == NULL) {
164
 
                // negotiate association
165
 
                LOG_DEBUG(caller->ambitolog, "Aceptando subAsociacion");
166
 
                caller->acceptSubAssoc(aNet, subAssoc);
167
 
        }
168
 
        else {
169
 
                // be a service class provider
170
 
                LOG_DEBUG(caller->ambitolog, "Invocando subOp SCP");
171
 
                caller->subOpSCP(subAssoc);
172
 
        }
173
 
}
174
 
 
175
 
CONDITION MoveAssociation::acceptSubAssoc(T_ASC_Network *aNet, T_ASC_Association **assoc) {
176
 
        CONDITION cond = ASC_NORMAL;
177
 
        
178
 
        const char* knownAbstractSyntaxes[] = {UID_VerificationSOPClass};
179
 
        
180
 
        //////  
181
 
        if (m_TLS)
182
 
    {
183
 
                 
184
 
                std::string cliCert = GetCliCert();
185
 
                std::string cliKey  = GetCliKey();
186
 
                GTLSTransportLayer* tLayer = new GTLSTransportLayer(DICOM_APPLICATION_REQUESTOR, NULL);
187
 
                if (tLayer == NULL)
188
 
                {
189
 
                        LOG_ERROR("C-MOVE SubAssoc", "unable to create TLS transport layer");
190
 
                        //return 1;
191
 
                        return EC_IllegalParameter;
192
 
                }
193
 
                tLayer->setCertificateFromString(cliCert);
194
 
                tLayer->setPrivateKeyFromString(cliKey);
195
 
                
196
 
                if (! tLayer->checkPrivateKeyMatchesCertificate())
197
 
                {
198
 
                        LOG_ERROR("C-MOVE SubAssoc", "private key and certificate do not match");
199
 
                        return EC_IllegalParameter;
200
 
                }
201
 
                
202
 
                tLayer->addSystemTrustedCertificates();
203
 
                
204
 
                if (m_Validate) {
205
 
                        tLayer->setCertificateVerification(DCV_requireCertificate);
206
 
                }
207
 
                else {
208
 
                        tLayer->setCertificateVerification(DCV_ignoreCertificate);
209
 
                }
210
 
                /*
211
 
                 if (opt_dhparam && ! (tLayer->setTempDHParameters(opt_dhparam)))
212
 
                 {
213
 
                 LOG_WARN("C-MOVE SubAssoc", "unable to load temporary DH parameters. Ignoring");
214
 
                 }
215
 
                 */
216
 
                
217
 
                cond = ASC_setTransportLayer(aNet, tLayer, 0);
218
 
                if (cond.bad())
219
 
                {
220
 
                        LOG_ERROR("C-MOVE SubAssoc", "Error al insertar capa de transporte segura: " << cond.text());
221
 
                        return EC_IllegalParameter;
222
 
                }
223
 
                
224
 
    }
225
 
        cond = ASC_receiveAssociation(aNet, assoc, m_maxReceivePDULength, NULL, NULL, m_TLS, DUL_BLOCK, 240);
226
 
        
227
 
        if (cond.bad()) {
228
 
                LOG_ERROR("C-MOVE SubAssoc", "No se pudo recibir la asociación" << cond.text());
229
 
        }
230
 
        
231
 
        if (cond.good() && assoc && *assoc && m_TLS) {
232
 
                cond = ASC_setTransportLayerType((*assoc)->params, m_TLS);
233
 
        
234
 
                if (cond.bad()) {
235
 
                        LOG_ERROR("C-MOVE SubAssoc", "No se pudo fijar la capa TLS sobre la asociación" << cond.text());
236
 
                }
237
 
        }
238
 
        if(cond.good()) {
239
 
 
240
 
                // accept the Verification SOP Class if presented */
241
 
                cond = ASC_acceptContextsWithPreferredTransferSyntaxes(
242
 
                        (*assoc)->params,
243
 
                        knownAbstractSyntaxes, DIM_OF(knownAbstractSyntaxes),
244
 
                        AllTransferSyntaxes, 3);
245
 
 
246
 
                if (cond.good()) {
247
 
                        cond = ASC_acceptContextsWithPreferredTransferSyntaxes(
248
 
                                (*assoc)->params,
249
 
                                dcmAllStorageSOPClassUIDs, numberOfAllDcmStorageSOPClassUIDs,
250
 
                                AllTransferSyntaxes, AllTransferSyntaxesCount);
251
 
                }
252
 
                else {
253
 
                        LOG_ERROR("C-MOVE SubAssoc", "No se pudo aceptar el Verification SOP Class aun estando presente: " << cond.text());
254
 
                }
255
 
        }
256
 
 
257
 
        bool reconocida = false;
258
 
        if (cond.good()) {
259
 
                cond = ASC_acknowledgeAssociation(*assoc);
260
 
                reconocida = true;
261
 
        }
262
 
        else {
263
 
                
264
 
                LOG_ERROR("C-MOVE SubAssoc", "No se pudo enviar el reconocimiento de la asociación" << cond.text());
265
 
        }
266
 
 
267
 
        if (cond.bad()) {
268
 
                if (reconocida) {
269
 
                        LOG_ERROR("C-MOVE SubAssoc", "Error al reconocer la asociación: " << cond.text());
270
 
                }
271
 
                ASC_releaseAssociation(*assoc);
272
 
                ASC_dropAssociation(*assoc);
273
 
                ASC_destroyAssociation(assoc);
274
 
        }
275
 
 
276
 
        return cond;
277
 
 
278
 
}
279
 
 
280
 
CONDITION MoveAssociation::subOpSCP(T_ASC_Association **subAssoc) {
281
 
        T_DIMSE_Message msg;
282
 
        T_ASC_PresentationContextID presID;
283
 
 
284
 
        /* just in case */
285
 
        if (!ASC_dataWaiting(*subAssoc, 0)) {
286
 
                LOG_TRACE(ambitolog, "No hay datos pendientes");
287
 
                return DIMSE_NODATAAVAILABLE;
288
 
        }
289
 
 
290
 
        OFCondition cond = DIMSE_receiveCommand(*subAssoc, DIMSE_BLOCKING, 0, &presID, &msg, NULL);
291
 
 
292
 
        if (cond == EC_Normal) {
293
 
                switch (msg.CommandField) {
294
 
                        case DIMSE_C_STORE_RQ:
295
 
                                LOG_TRACE(ambitolog, "Invocando C-STORE_RQ");
296
 
                                cond = storeSCP(*subAssoc, &msg, presID);
297
 
                                break;
298
 
                        case DIMSE_C_ECHO_RQ:
299
 
                                LOG_TRACE(ambitolog, "Invocando C-ECHO_RQ");
300
 
                                cond = echoSCP(*subAssoc, &msg, presID);
301
 
                                break;
302
 
                        default:
303
 
                                LOG_ERROR(ambitolog, "Tipo de comando incorrecto. S�lo se aceptan C-STORE_RQ o C-ECHO_RQ en esta etapa" << cond.text());
304
 
                                cond = DIMSE_BADCOMMANDTYPE;
305
 
                                break;
306
 
                }
307
 
        }
308
 
 
309
 
        // clean up on association termination
310
 
        if (cond == DUL_PEERREQUESTEDRELEASE) {
311
 
                LOG_TRACE(ambitolog, "El PACS remoto solicitó el cierre de la asociación");
312
 
                ASC_acknowledgeRelease(*subAssoc);
313
 
 
314
 
                ASC_dropSCPAssociation(*subAssoc);
315
 
                ASC_destroyAssociation(subAssoc);
316
 
 
317
 
                return cond;
318
 
        }
319
 
        else if (cond == DUL_PEERABORTEDASSOCIATION) {
320
 
                LOG_ERROR(ambitolog, "El PACS remoto abortó la asociación"  << cond.text());
321
 
 
322
 
                ASC_dropSCPAssociation(*subAssoc);
323
 
                ASC_destroyAssociation(subAssoc);
324
 
                return cond;
325
 
 
326
 
        }
327
 
        else if (cond != EC_Normal) {
328
 
                LOG_ERROR(ambitolog, "Ha ocurrido un error y se abortará la asociación"  << cond.text());
329
 
                // some kind of error so abort the association
330
 
                ASC_releaseAssociation(*subAssoc);
331
 
 
332
 
                ASC_dropSCPAssociation(*subAssoc);
333
 
                ASC_destroyAssociation(subAssoc);
334
 
                return cond;
335
 
        }
336
 
 
337
 
        return cond;
338
 
}
339
 
 
340
 
CONDITION MoveAssociation::storeSCP(T_ASC_Association *assoc, T_DIMSE_Message *msg, T_ASC_PresentationContextID presID) {
341
 
        CONDITION cond;
342
 
        T_DIMSE_C_StoreRQ* req;
343
 
 
344
 
        req = &msg->msg.CStoreRQ;
345
 
 
346
 
        StoreCallbackInfo callbackData;
347
 
        callbackData.pCaller = this;
348
 
        callbackData.assoc = assoc;
349
 
        callbackData.lastTick = std::clock();
350
 
 
351
 
        std::string fileName = GNC::Entorno::Instance()->CreateGinkgoTempFile();
352
 
 
353
 
        cond = DIMSE_storeProvider(assoc, presID, req, fileName.c_str(), 1,
354
 
                NULL, storeSCPCallback, (void*) & callbackData,
355
 
                DIMSE_BLOCKING, 0);
356
 
 
357
 
        if (cond.good()) {
358
 
                //we are going to read received file dataset
359
 
                DcmFileFormat ff;
360
 
                ff.loadFile(fileName.c_str(), EXS_Unknown, EGL_noChange, DCM_TagInfoLength);
361
 
                DcmDataset* imageDataSet = ff.getDataset();
362
 
 
363
 
                if ((imageDataSet)) {
364
 
                        // do not duplicate the dataset, let the user do this
365
 
                        // if he wants to
366
 
                        OnFileReceived(fileName, imageDataSet);
367
 
                }
368
 
        }
369
 
 
370
 
        return cond;
371
 
}
372
 
 
373
 
void MoveAssociation::storeSCPCallback(void *callbackData, T_DIMSE_StoreProgress *progress, T_DIMSE_C_StoreRQ *req, char* imageFileName, DcmDataset ** /*imageDataSet*/, T_DIMSE_C_StoreRSP *rsp, DcmDataset **statusDetail) {
374
 
        DIC_UI sopClass;
375
 
        DIC_UI sopInstance;
376
 
 
377
 
        StoreCallbackInfo *cbdata = (StoreCallbackInfo*) callbackData;
378
 
        MoveAssociation* caller = cbdata->pCaller;
379
 
 
380
 
        if (progress->state == DIMSE_StoreBegin) {
381
 
                caller->m_bytesDescargados += progress->totalBytes;
382
 
                GNC::GCS::Permisos::EstadoPermiso estado = GNC::GCS::ControladorPermisos::Instance()->Get("core.pacs.limits", "study_size");
383
 
                if (estado) {
384
 
                        if (estado.ObtenerValor<long>() < (caller->m_bytesDescargados / 1024) ) {
385
 
                                caller->m_errorMessage = _Std("Study download size limit exceded");
386
 
                                cbdata->pCaller->Stop();
387
 
                                rsp->DimseStatus = STATUS_MOVE_Cancel_SubOperationsTerminatedDueToCancelIndication;
388
 
                                ASC_releaseAssociation(cbdata->assoc);
389
 
                                LOG_INFO(caller->ambitolog, "Study download size limit exceded");
390
 
                                return;
391
 
                        }
392
 
                }
393
 
                cbdata->lastTick = std::clock();
394
 
        }
395
 
        else if (progress->state == DIMSE_StoreProgressing) {
396
 
                
397
 
                std::clock_t curTick = std::clock();
398
 
                if ( (curTick - cbdata->lastTick) > (CLOCKS_PER_SEC >> 1) ) {
399
 
                        cbdata->lastTick = curTick;
400
 
                        std::stringstream ostr;
401
 
                        ostr << caller->m_mensaje;
402
 
                        ostr.setf(std::ios::floatfield, std::ios::fixed );
403
 
                        ostr.precision(2);
404
 
                        ostr <<  " (" << caller->TasaTransferencia(progress->progressBytes) << " kb/s)";
405
 
                        std::string msg(ostr.str());
406
 
                        if(!caller->NotificarProgreso(((float)progress->progressBytes/progress->totalBytes),msg))
407
 
                        {
408
 
                                cbdata->pCaller->Stop();
409
 
                                rsp->DimseStatus = STATUS_MOVE_Cancel_SubOperationsTerminatedDueToCancelIndication;
410
 
                                ASC_releaseAssociation(cbdata->assoc);
411
 
                                LOG_INFO(caller->ambitolog, "Operation canceled by user");
412
 
                                return;
413
 
                        }
414
 
                }
415
 
        }
416
 
        else if (progress->state == DIMSE_StoreEnd) {
417
 
                LOG_TRACE(caller->ambitolog, "storeSCPCallback(). DIMSE_StoreEnd");
418
 
                *statusDetail = NULL; /* no status detail */
419
 
                caller->ResetearMedida();
420
 
 
421
 
                /* could save the image somewhere else, put it in database, etc */
422
 
                rsp->DimseStatus = STATUS_Success;
423
 
 
424
 
                //we are going to read received file dataset
425
 
                DcmFileFormat ff;
426
 
                ff.loadFile(imageFileName, EXS_Unknown, EGL_noChange, DCM_TagInfoLength);
427
 
                DcmDataset* imageDataSet = ff.getDataset();
428
 
                /* should really check the image to make sure it is consistent,
429
 
                * that its sopClass and sopInstance correspond with those in
430
 
                * the request.
431
 
                */
432
 
                if (rsp->DimseStatus == STATUS_Success) {
433
 
                        /* which SOP class and SOP instance ? */
434
 
                        if (!DU_findSOPClassAndInstanceInDataSet(imageDataSet, sopClass, sopInstance)) {
435
 
                                rsp->DimseStatus = STATUS_STORE_Error_CannotUnderstand;
436
 
                                LOG_ERROR(caller->ambitolog, "No se pudo encontrar SOPClass o SOPInstanceUID en el dataset");
437
 
                        }
438
 
                        else if (strcmp(sopClass, req->AffectedSOPClassUID) != 0) {
439
 
                                rsp->DimseStatus = STATUS_STORE_Error_DataSetDoesNotMatchSOPClass;
440
 
                                LOG_ERROR(caller->ambitolog, "El SOPClass del dataset(" << sopClass << ") no coincide con el SOPClass requerido (" << req->AffectedSOPClassUID << ")");
441
 
                        }
442
 
                        else if (strcmp(sopInstance, req->AffectedSOPInstanceUID) != 0) {
443
 
                                rsp->DimseStatus = STATUS_STORE_Error_DataSetDoesNotMatchSOPClass;
444
 
                                LOG_ERROR(caller->ambitolog, "El SOPInstance del dataset(" << sopInstance << ") no coincide con el SOPInstanceUID requerido (" << req->AffectedSOPInstanceUID << ")");
445
 
                        }
446
 
                }
447
 
        }
448
 
 
449
 
}
450
 
 
451
 
CONDITION MoveAssociation::echoSCP(T_ASC_Association *assoc, T_DIMSE_Message *msg, T_ASC_PresentationContextID presID) {
452
 
        CONDITION cond;
453
 
 
454
 
        // the echo succeeded !!
455
 
        cond = DIMSE_sendEchoResponse(assoc, presID, &msg->msg.CEchoRQ, STATUS_Success, NULL);
456
 
 
457
 
        return cond;
458
 
}
459
 
 
460
 
void MoveAssociation::OnFileReceived(const std::string& fileName, DcmDataset* dset) {
461
 
        if (m_pModelo != NULL) {
462
 
                OFString OFEstudioUId;
463
 
                if (dset->findAndGetOFString(DCM_StudyInstanceUID, OFEstudioUId).good()) {
464
 
                        OFString OFPacienteUID;
465
 
                        std::string PacienteUID;
466
 
                        if (dset->findAndGetOFString(DCM_PatientID, OFPacienteUID).good()) {
467
 
                                PacienteUID.assign(OFPacienteUID.c_str());
468
 
                        }
469
 
 
470
 
                        OFString OFPacienteNombre;
471
 
                        std::string PacienteNombre;
472
 
                        if (dset->findAndGetOFString(DCM_PatientName, OFPacienteNombre).good()) {
473
 
                                PacienteNombre.assign(OFPacienteNombre.c_str());
474
 
                        }
475
 
 
476
 
                        OFString OFPacienteFechaNacimiento;
477
 
                        std::string PacienteFechaNacimiento;
478
 
 
479
 
                        if (dset->findAndGetOFString(DCM_PatientBirthDate, OFPacienteFechaNacimiento).good()) {
480
 
                                PacienteFechaNacimiento.assign(OFPacienteFechaNacimiento.c_str());
481
 
                        }
482
 
 
483
 
 
484
 
                        OFString OFPacienteSexo;
485
 
                        std::string PacienteSexo;
486
 
                        if (dset->findAndGetOFString(DCM_PatientSex, OFPacienteSexo).good()) {
487
 
                                PacienteSexo.assign(OFPacienteSexo.c_str());
488
 
                        }
489
 
 
490
 
                        const IModeloPaciente& paciente = m_pModelo->InsertarPaciente(PacienteUID, PacienteNombre, PacienteFechaNacimiento, PacienteSexo);
491
 
 
492
 
                        OFString OFEstudioUID;
493
 
                        std::string EstudioUID;
494
 
                        if (dset->findAndGetOFString(DCM_StudyInstanceUID, OFEstudioUID).good()) {
495
 
                                EstudioUID.assign(OFEstudioUID.c_str());
496
 
                        }
497
 
 
498
 
                        OFString OFEAccNumber;
499
 
                        std::string AccNumber;
500
 
                        if (dset->findAndGetOFString(DCM_AccessionNumber, OFEAccNumber).good()) {
501
 
                                AccNumber.assign(OFEAccNumber.c_str());
502
 
                        }
503
 
 
504
 
                        OFString OFEstudioDescripcion;
505
 
                        std::string EstudioDescripcion;
506
 
                        if (dset->findAndGetOFString(DCM_StudyDescription, OFEstudioDescripcion).good()) {
507
 
                                EstudioDescripcion.assign(OFEstudioDescripcion.c_str());
508
 
                        }
509
 
 
510
 
                        OFString OFEstudioModalidad;
511
 
                        std::string EstudioModalidad;
512
 
                        if (dset->findAndGetOFString(DCM_ModalitiesInStudy, OFEstudioModalidad).good()) {
513
 
                                EstudioModalidad.assign(OFEstudioModalidad.c_str());
514
 
                        }
515
 
 
516
 
                        OFString OFEstudioFecha;
517
 
                        std::string EstudioFecha;
518
 
                        if (dset->findAndGetOFString(DCM_StudyDate, OFEstudioFecha).good()) {
519
 
                                EstudioFecha.assign(OFEstudioFecha.c_str());
520
 
                        }
521
 
 
522
 
                        OFString OFEstudioHora;
523
 
                        std::string EstudioHora;
524
 
                        if (dset->findAndGetOFString(DCM_StudyTime, OFEstudioHora).good()) {
525
 
                                EstudioHora.assign(OFEstudioHora.c_str());
526
 
                        }
527
 
 
528
 
 
529
 
                        OFString OFEstudioDoctor;
530
 
                        std::string EstudioDoctor;
531
 
                        if (dset->findAndGetOFString(DCM_ReferringPhysicianName, OFEstudioDoctor).good()) {
532
 
                                EstudioDoctor.assign(OFEstudioDoctor.c_str());
533
 
                        }
534
 
 
535
 
                        m_pModelo->InsertarEstudio(paciente.GetUID(), EstudioUID, AccNumber, EstudioDescripcion, EstudioModalidad, EstudioFecha, EstudioHora, EstudioDoctor);
536
 
 
537
 
                        OFString OFSerieUID;
538
 
                        std::string SerieUID;
539
 
                        if (dset->findAndGetOFString(DCM_SeriesInstanceUID, OFSerieUID).good()) {
540
 
                                SerieUID.assign(OFSerieUID.c_str());
541
 
                        }
542
 
 
543
 
                        OFString OFSerieTipo;
544
 
                        std::string SerieTipo;
545
 
                        if (dset->findAndGetOFString(DCM_SeriesType, OFSerieTipo).good()) {
546
 
                                SerieTipo.assign(OFSerieTipo.c_str());
547
 
                        }
548
 
 
549
 
                        OFString OFSerieFecha;
550
 
                        std::string SerieFecha;
551
 
                        if (dset->findAndGetOFString(DCM_SeriesDate, OFSerieFecha).good()) {
552
 
                                SerieFecha.assign(OFSerieFecha.c_str());
553
 
                        }
554
 
 
555
 
                        OFString OFSerieHora;
556
 
                        std::string SerieHora;
557
 
                        if (dset->findAndGetOFString(DCM_SeriesTime, OFSerieHora).good()) {
558
 
                                SerieHora.assign(OFSerieHora.c_str());
559
 
                        }
560
 
 
561
 
                        OFString OFSerieDescripcion;
562
 
                        std::string SerieDescripcion;
563
 
                        if (dset->findAndGetOFString(DCM_SeriesDescription, OFSerieDescripcion).good()) {
564
 
                                SerieDescripcion.assign(OFSerieDescripcion.c_str());
565
 
                        }
566
 
 
567
 
                        OFString OFSerieNumero;
568
 
                        std::string SerieNumero;
569
 
                        if (dset->findAndGetOFString(DCM_NumberOfSeriesRelatedInstances, OFSerieNumero).good()) {
570
 
                                SerieNumero.assign(OFSerieNumero.c_str());
571
 
                        }
572
 
 
573
 
                        OFString OFSerieDoctor;
574
 
                        std::string SerieDoctor;
575
 
                        if (dset->findAndGetOFString(DCM_ReferringPhysicianName, OFSerieDoctor).good()) {
576
 
                                SerieDoctor.assign(OFSerieDoctor.c_str());
577
 
                        }
578
 
 
579
 
                        m_pModelo->InsertarSerie(EstudioUID, SerieUID, SerieTipo, SerieFecha, SerieHora, SerieDescripcion,SerieNumero,SerieDoctor);
580
 
 
581
 
                        OFString OFUIDImagen;
582
 
                        std::string UIDImagen;
583
 
                        if (dset->findAndGetOFString(DCM_SOPInstanceUID, OFUIDImagen).good()) {
584
 
                                UIDImagen.assign(OFUIDImagen.c_str());
585
 
                                m_pModelo->InsertarImagen(SerieUID,UIDImagen);
586
 
                        }
587
 
                }
588
 
        }
589
 
        if (m_pHandler != NULL) {
590
 
                m_pHandler->Store(fileName, dset);
591
 
        }
592
 
}
593
 
 
594
 
void MoveAssociation::SetCallbackHandler(IStoreCallBack * handler) {
595
 
        m_pHandler = handler;
596
 
}
597
 
 
598
 
float MoveAssociation::TasaTransferencia(int bytesDescargados)
599
 
{
600
 
        time_t nuevoInstante = time(NULL);
601
 
        const double tiempo = difftime(nuevoInstante,m_medida.m_instante);
602
 
        if(tiempo>0.15f){
603
 
                if(bytesDescargados > m_medida.bytesDescargados) {
604
 
                        const double bytesRecibidosPeriodo = bytesDescargados - m_medida.bytesDescargados;
605
 
                        m_medida.oldTasa = ( ((float)bytesRecibidosPeriodo/1024.0f)/tiempo );
606
 
                        m_medida.bytesDescargados = bytesDescargados;
607
 
                        m_medida.m_instante = nuevoInstante;
608
 
                }
609
 
        }
610
 
        return m_medida.oldTasa;
611
 
}
612
 
 
613
 
void MoveAssociation::ResetearMedida(bool clearTasa) {
614
 
        m_medida.bytesDescargados = 0;
615
 
        m_medida.m_instante = time(NULL);
616
 
        if(clearTasa) {
617
 
                m_medida.oldTasa=0.0f;
618
 
        }
 
138
        if(m_errorMessage != "" || rsp.NumberOfFailedSubOperations > 0 ) {
 
139
                if (m_errorMessage.size() == 0) {
 
140
                        m_errorMessage = "Some operations failed";
 
141
                }
 
142
                return makeOFCondition(OFM_dcmnet, 18, OF_error, m_errorMessage.c_str());
 
143
        }
 
144
 
 
145
        return cond;
619
146
}
620
147