6
* Copyright 2008-10 MetaEmotion S.L. All rights reserved.
7
* http://ginkgo-cadx.com
9
* This file is licensed under LGPL v3 license.
10
* See License.txt for details
13
#define LOGGER "C-GET"
14
#include <api/icontroladorlog.h>
15
#include <main/controllers/controladorlog.h>
16
#include <api/imodelodicom.h>
17
#include <main/controllers/controladorpermisos.h>
18
#include <api/icontroladorimportacionpacs.h>
19
#include <api/internacionalizacion.h>
20
#include <api/icontextoestudio.h>
22
#include "istorecallback.h"
24
#include "dicomnetwork.h"
25
#include "dicomgetassociation.h"
27
#include <dcmtk/dcmnet/diutil.h>
28
#include <dcmtk/dcmjpeg/djencode.h>
29
#include <dcmtk/dcmjpeg/djrplol.h>
30
#include <dcmtk/dcmdata/dcuid.h>
31
#include <dcmtk/dcmdata/dcdatset.h>
32
#include <dcmtk/dcmdata/dcdeftag.h>
34
std::string GetAssociation::m_errorMessage = "";
36
GetAssociation::GetAssociation(const std::string& _ambitolog, IModeloDicom* pModelo) : FindAssociation(_ambitolog) {
37
m_abstractSyntax = (char*) UID_GETStudyRootQueryRetrieveInformationModel;
38
m_maxReceivePDULength = ASC_DEFAULTMAXPDU;
44
m_bytesDescargados = 0;
45
m_wellKnownNumResults = 0;
48
GetAssociation::~GetAssociation() { }
50
void GetAssociation::Create(const std::string& title, const std::string& peer, int port, const std::string& ouraet, /*int ourPort,*/ const char *abstractSyntax) {
51
Association::Create(title, peer, port, ouraet, abstractSyntax);
54
void GetAssociation::SetWellKnownNumResults(unsigned int numResults){
55
m_wellKnownNumResults = numResults;
58
void GetAssociation::SetModelo(IModeloDicom* pModelo) {
62
CONDITION GetAssociation::SendObject(DcmDataset *dataset) {
63
return getSCU(dataset);
66
void GetAssociation::SetStorageSOPClasses(const SOPClassList& SOPClasses)
68
this->SOPClasses = SOPClasses;
71
void GetAssociation::OnAddPresentationContext(T_ASC_Parameters * params) {
75
CONDITION cond = ASC_addPresentationContext(params, pid, m_abstractSyntax, AllTransferSyntaxes, 3);
77
LOG_ERROR(ambitolog, "Unable to add GETStudyRootQueryRetrieveInformationModel presentation context");
83
if (SOPClasses.size() > 0) {
84
for (unsigned int i = 0; pid <= 255 && i < (unsigned int) numberOfDcmLongSCUStorageSOPClassUIDs && cond.good(); ++i) {
85
if ( SOPClasses.find(dcmLongSCUStorageSOPClassUIDs[i]) != SOPClasses.end() ) {
87
for (unsigned int j = 0; pid <= 255 && j < AllTransferSyntaxesCount && cond.good(); j++) {
88
cond = ASC_addPresentationContext(params, pid, dcmLongSCUStorageSOPClassUIDs[i], &AllTransferSyntaxes[j], 1);
95
LOG_WARN("C-GET", "Too many PresentationContexts setted");
99
for (unsigned int i = 0; pid <= 255 && i < (unsigned int) numberOfDcmLongSCUStorageSOPClassUIDs && cond.good(); ++i) {
100
cond = ASC_addPresentationContext(params, pid, dcmLongSCUStorageSOPClassUIDs[i], AllTransferSyntaxes, AllTransferSyntaxesCount);
104
LOG_WARN("C-GET", "Too many PresentationContexts setted");
110
selectReadable(T_ASC_Association *assoc,
111
T_ASC_Network *net, T_ASC_Association *subAssoc,
112
T_DIMSE_BlockingMode blockMode, int timeout)
114
T_ASC_Association *assocList[2];
117
if (net != NULL && subAssoc == NULL) {
118
if (ASC_associationWaiting(net, 0)) {
119
/* association request waiting on network */
123
assocList[0] = assoc;
125
assocList[1] = subAssoc;
126
if (subAssoc != NULL) assocCount++;
127
if (subAssoc == NULL) {
128
timeout = 1; /* poll wait until an assoc req or move rsp */
130
if (blockMode == DIMSE_BLOCKING) {
131
timeout = 10000; /* a long time */
134
if (!ASC_selectReadableAssociation(assocList, assocCount, timeout)) {
138
if (assocList[0] != NULL) {
139
/* main association readable */
142
if (assocList[1] != NULL) {
143
/* sub association readable */
146
/* should not be reached */
151
OFCondition MDIMSE_getUser(
152
T_ASC_Association* assoc,
153
GetAssociation* getassoc,
154
T_ASC_PresentationContextID presID,
155
T_DIMSE_C_GetRQ *request,
156
DcmDataset *requestIdentifiers,
157
T_DIMSE_BlockingMode blockMode, int timeout,
159
T_DIMSE_C_GetRSP * /*response*/, DcmDataset **statusDetail,
162
T_DIMSE_Message req, rsp;
164
int responseCount = 0;
165
T_ASC_Association *subAssoc = NULL;
166
DIC_US status = STATUS_Pending;
168
if (requestIdentifiers == NULL) return DIMSE_NULLKEY;
170
bzero((char*)&req, sizeof(req));
171
bzero((char*)&rsp, sizeof(rsp));
173
req.CommandField = DIMSE_C_GET_RQ;
174
request->DataSetType = DIMSE_DATASET_PRESENT;
175
req.msg.CGetRQ = *request;
177
msgId = request->MessageID;
179
LOG_DEBUG("C-GET", "Accepted presID " << (int)presID);
181
OFCondition cond = DIMSE_sendMessageUsingMemoryData(assoc, presID, &req,
182
NULL, requestIdentifiers,
184
if (cond != EC_Normal) {
188
/* receive responses */
190
while (cond == EC_Normal && status == STATUS_Pending) {
192
/* if user wants, multiplex between net/subAssoc
193
* and responses over main assoc.
195
switch (selectReadable(assoc, getassoc->GetNetwork()->GetDcmtkNet(), subAssoc, blockMode, timeout)) {
197
/* none are readble, timeout */
198
if (blockMode == DIMSE_BLOCKING) {
199
continue; /* continue with while loop */
201
return DIMSE_NODATAAVAILABLE;
203
/* break; */ // never reached after continue or return.
205
/* main association readable */
208
/* net/subAssoc readable */
209
getassoc->subOpCallback(NULL, getassoc->GetNetwork()->GetDcmtkNet(), &subAssoc);
210
continue; /* continue with main loop */
211
/* break; */ // never reached after continue statement
214
bzero((char*)&rsp, sizeof(rsp));
216
cond = DIMSE_receiveCommand(assoc, blockMode, timeout, &presID,
218
if (cond != EC_Normal) {
224
DIMSE_dumpMessage(str, rsp, DIMSE_INCOMING);
225
LOG_DEBUG("C-GET", "Command received" << std::endl << str.c_str());
228
switch (rsp.CommandField){
229
case DIMSE_C_STORE_RQ:
231
if (rsp.msg.CStoreRQ.DataSetType != DIMSE_DATASET_NULL) {
232
cond = getassoc->storeSCP(assoc, &rsp, presID);
233
if (cond != EC_Normal) {
242
case DIMSE_C_GET_RSP:
244
if (rsp.msg.CGetRSP.MessageIDBeingRespondedTo != msgId)
246
std::stringstream ss;
247
ss << "DIMSE: Unexpected Response MsgId: " << rsp.msg.CGetRSP.MessageIDBeingRespondedTo << " (expected: " << msgId << ")";
248
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, ss.str().c_str());
251
status = rsp.msg.CGetRSP.DimseStatus;
256
if (*statusDetail != NULL) {
257
DCMNET_WARN(DIMSE_warn_str(assoc) << "getUser: Pending with statusDetail, ignoring detail");
258
delete *statusDetail;
259
*statusDetail = NULL;
261
if (rsp.msg.CGetRSP.DataSetType != DIMSE_DATASET_NULL) {
262
DCMNET_WARN(DIMSE_warn_str(assoc) << "getUser: Status Pending, but DataSetType!=NULL");
263
DCMNET_WARN(DIMSE_warn_str(assoc) << "Assuming NO response identifiers are present");
270
if (rsp.msg.CGetRSP.DataSetType != DIMSE_DATASET_NULL) {
271
cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, timeout,
272
&presID, rspIds, NULL, NULL);
273
if (cond != EC_Normal) {
283
std::stringstream ss;
284
ss << "DIMSE: Unexpected Response Command Field: " << (unsigned)rsp.CommandField;
285
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, ss.str().c_str());
292
/* do remaining sub-association work, we may receive a non-pending
293
* status before the sub-association has cleaned up.
295
while (subAssoc != NULL) {
296
getassoc->subOpCallback(getassoc, getassoc->GetNetwork()->GetDcmtkNet(), &subAssoc);
304
CONDITION GetAssociation::getSCU(DcmDataset *pdset) {
306
T_ASC_PresentationContextID presId;
308
T_DIMSE_C_GetRSP rsp;
309
DIC_US msgId = assoc->nextMsgID++;
310
DcmDataset* rspIds = NULL;
311
const char* sopClass;
312
DcmDataset* statusDetail = NULL;
313
GetCallbackInfo callbackData;
314
StoreCallbackInfo storeCallbackData;
317
LOG_ERROR(ambitolog, "Dataset nulo en getSCU");
318
return DIMSE_NULLKEY;
323
ASC_dumpParameters(str, assoc->params, ASC_ASSOC_AC);
324
LOG_DEBUG("C-GET", str.c_str());
328
//sopClass = m_abstractSyntaxMove;
329
sopClass = m_abstractSyntax;
331
// which presentation context should be used
332
presId = ASC_findAcceptedPresentationContextID(assoc, sopClass);
335
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
338
callbackData.assoc = assoc;
339
callbackData.presId = presId;
340
callbackData.pCaller = this;
342
storeCallbackData.assoc = assoc;
343
//storeCallbackData.presId = presId;
344
storeCallbackData.pCaller = this;
346
req.MessageID = msgId;
347
strcpy(req.AffectedSOPClassUID, sopClass);
348
req.Priority = DIMSE_PRIORITY_HIGH;
349
req.DataSetType = DIMSE_DATASET_PRESENT;
351
ResetearMedida(true);
356
DIMSE_dumpMessage(str, req, DIMSE_OUTGOING, pdset, presId);
357
LOG_DEBUG("C-GET", str.c_str());
361
cond = MDIMSE_getUser(
369
&rsp, &statusDetail, &rspIds);
372
LOG_DEBUG(ambitolog, "DIMSE_getUser(): " << cond.text() );
374
if (statusDetail != NULL) {
375
LOG_DEBUG(ambitolog, "DIMSE_getUser(): Estado: " << std::endl << DumpDataset(statusDetail));
379
if (rspIds != NULL) {
384
if(m_errorMessage != "")
386
throw GIL::DICOM::PACSException(m_errorMessage, "Adquisition");
392
void GetAssociation::getCallback(void * /*callbackData*/, T_DIMSE_C_GetRQ * /*request*/, int /*responseCount*/, T_DIMSE_C_GetRSP * /*response*/)
397
void GetAssociation::subOpCallback(void *pCaller, T_ASC_Network *aNet, T_ASC_Association **subAssoc) {
398
GetAssociation* caller = (GetAssociation*) pCaller;
400
if (caller->GetNetwork() == NULL) {
404
wxString msg = wxString::Format(_("Downloading file %d"), ++caller->m_numeroImagenes);
405
caller->m_mensaje = std::string(msg.ToUTF8());
406
LOG_DEBUG(caller->ambitolog, caller->m_mensaje);
407
caller->NotificarProgreso((float)caller->m_numeroImagenes/100,caller->m_mensaje);
409
if (*subAssoc == NULL) {
410
// negotiate association
411
LOG_DEBUG(caller->ambitolog, "Aceptando subAsociaci�n");
412
caller->acceptSubAssoc(aNet, subAssoc);
415
// be a service class provider
416
LOG_DEBUG(caller->ambitolog, "Invocando subOp SCP");
417
caller->subOpSCP(subAssoc);
421
CONDITION GetAssociation::acceptSubAssoc(T_ASC_Network* /*aNet*/, T_ASC_Association** /*assoc*/) {
422
CONDITION cond = ASC_NORMAL;
428
CONDITION GetAssociation::subOpSCP(T_ASC_Association **subAssoc) {
430
T_ASC_PresentationContextID presID;
433
if (!ASC_dataWaiting(*subAssoc, 0)) {
434
LOG_TRACE(ambitolog, "No hay datos pendientes");
435
return DIMSE_NODATAAVAILABLE;
438
OFCondition cond = DIMSE_receiveCommand(*subAssoc, DIMSE_BLOCKING, 0, &presID, &msg, NULL);
444
if (cond == EC_Normal) {
445
switch (msg.CommandField) {
446
case DIMSE_C_STORE_RQ:
447
LOG_TRACE(ambitolog, "Invocando C-STORE_RQ");
448
cond = storeSCP(*subAssoc, &msg, presID);
450
case DIMSE_C_ECHO_RQ:
451
LOG_TRACE(ambitolog, "Invocando C-ECHO_RQ");
452
cond = echoSCP(*subAssoc, &msg, presID);
455
LOG_ERROR(ambitolog, "Tipo de comando incorrecto. S�lo se aceptan C-STORE_RQ o C-ECHO_RQ en esta etapa" << cond.text());
456
cond = DIMSE_BADCOMMANDTYPE;
461
// clean up on association termination
462
if (cond == DUL_PEERREQUESTEDRELEASE) {
463
cond = ASC_acknowledgeRelease(*subAssoc);
464
ASC_dropSCPAssociation(*subAssoc);
465
ASC_destroyAssociation(subAssoc);
468
else if (cond == DUL_PEERABORTEDASSOCIATION) {
469
LOG_ERROR(ambitolog, "El PACS remoto abort� la asociaci�n" << cond.text());
471
else if (cond != EC_Normal) {
472
LOG_ERROR(ambitolog, "Ha ocurrido un error y se abortar� la asociaci�n" << cond.text());
473
// some kind of error so abort the association
474
cond = ASC_abortAssociation(*subAssoc);
477
if (cond != EC_Normal) {
478
ASC_dropAssociation(*subAssoc);
479
ASC_destroyAssociation(subAssoc);
484
CONDITION GetAssociation::storeSCP(T_ASC_Association *assoc, T_DIMSE_Message *msg, T_ASC_PresentationContextID presID) {
486
T_DIMSE_C_StoreRQ* req;
487
DcmDataset *dset = new DcmDataset;
489
req = &msg->msg.CStoreRQ;
491
StoreCallbackInfo callbackData;
492
callbackData.dataset = dset;
493
callbackData.pCaller = this;
494
callbackData.assoc = assoc;
496
cond = DIMSE_storeProvider(assoc, presID, req, (char *) NULL, 1,
497
&dset, storeSCPCallback, (void*) & callbackData,
504
void GetAssociation::storeSCPCallback(void *callbackData, T_DIMSE_StoreProgress *progress, T_DIMSE_C_StoreRQ *req, char* /*imageFileName*/, DcmDataset **imageDataSet, T_DIMSE_C_StoreRSP *rsp, DcmDataset **statusDetail) {
508
StoreCallbackInfo *cbdata = (StoreCallbackInfo*) callbackData;
509
GetAssociation* caller = cbdata->pCaller;
511
float partial = 0.0f;
514
if (caller->m_wellKnownNumResults > 0 ) {
515
step = 1.0f / (float) caller->m_wellKnownNumResults;
516
partial = (float)caller->m_numeroImagenes * step;
522
if (progress->state == DIMSE_StoreBegin) {
524
if (caller->m_wellKnownNumResults > 0) {
525
msg = wxString::Format(_("Downloading file %d/%d"), caller->m_numeroImagenes + 1, caller->m_wellKnownNumResults );
528
msg = wxString::Format(_("Downloading file %d"), caller->m_numeroImagenes + 1 );
530
caller->m_mensaje = std::string(msg.ToUTF8());
531
LOG_DEBUG(caller->ambitolog, caller->m_mensaje);
533
if (!caller->NotificarProgreso((float) partial, caller->m_mensaje) ) {
534
rsp->DimseStatus = STATUS_STORE_Refused_OutOfResources;
536
ASC_releaseAssociation(caller->assoc);
537
LOG_INFO(caller->ambitolog, "Operation canceled by user");
541
caller->m_bytesDescargados += progress->totalBytes;
542
GNC::GCS::Permisos::EstadoPermiso estado = GNC::GCS::ControladorPermisos::Instance()->Get("core.pacs.limits", "study_size");
544
if (estado.ObtenerValor<long>() < (caller->m_bytesDescargados / 1024) ) {
545
caller->m_errorMessage = _Std("Study download size limit exceded");
546
rsp->DimseStatus = STATUS_STORE_Refused_OutOfResources;
548
ASC_releaseAssociation(caller->assoc);
555
if (progress->state == DIMSE_StoreProgressing) {
556
//si ha pasado medio segundo...
557
std::stringstream ostr;
558
ostr << caller->m_mensaje;
559
ostr.setf(std::ios::floatfield, std::ios::fixed );
561
ostr << " (" << caller->TasaTransferencia(progress->progressBytes) << " kb/s)";
562
std::string msg(ostr.str());
563
if(!caller->NotificarProgreso( partial + step * ((float)progress->progressBytes/(float)progress->totalBytes), msg) )
565
rsp->DimseStatus = STATUS_STORE_Refused_OutOfResources;
566
OFCondition cond = ASC_releaseAssociation(cbdata->assoc);
571
if (progress->state == DIMSE_StoreEnd) {
572
LOG_TRACE(caller->ambitolog, "storeSCPCallback(). DIMSE_StoreEnd");
573
caller->m_numeroImagenes++;
574
*statusDetail = NULL; /* no status detail */
575
caller->ResetearMedida();
577
/* could save the image somewhere else, put it in database, etc */
578
rsp->DimseStatus = STATUS_Success;
580
if ((imageDataSet) && (*imageDataSet)) {
581
// do not duplicate the dataset, let the user do this
583
caller->OnResponseReceived(cbdata->dataset);
586
/* should really check the image to make sure it is consistent,
587
* that its sopClass and sopInstance correspond with those in
590
if (rsp->DimseStatus == STATUS_Success) {
591
/* which SOP class and SOP instance ? */
592
if (!DU_findSOPClassAndInstanceInDataSet(cbdata->dataset, sopClass, sopInstance)) {
593
rsp->DimseStatus = STATUS_STORE_Error_DataSetDoesNotMatchSOPClass;
594
LOG_ERROR(caller->ambitolog, "No se pudo encontrar SOPClass o SOPInstanceUID en el dataset");
596
else if (strcmp(sopClass, req->AffectedSOPClassUID) != 0) {
597
rsp->DimseStatus = STATUS_STORE_Error_DataSetDoesNotMatchSOPClass;
598
LOG_ERROR(caller->ambitolog, "El SOPClass del dataset(" << sopClass << ") no coincide con el SOPClass requerido (" << req->AffectedSOPClassUID << ")");
600
else if (strcmp(sopInstance, req->AffectedSOPInstanceUID) != 0) {
601
rsp->DimseStatus = STATUS_STORE_Error_DataSetDoesNotMatchSOPClass;
602
LOG_ERROR(caller->ambitolog, "El SOPInstance del dataset(" << sopInstance << ") no coincide con el SOPInstanceUID requerido (" << req->AffectedSOPInstanceUID << ")");
608
CONDITION GetAssociation::echoSCP(T_ASC_Association *assoc, T_DIMSE_Message *msg, T_ASC_PresentationContextID presID) {
611
// the echo succeeded !!
612
cond = DIMSE_sendEchoResponse(assoc, presID, &msg->msg.CEchoRQ, STATUS_Success, NULL);
617
void GetAssociation::OnResponseReceived(DcmDataset* dset) {
618
if (m_pHandler != NULL) {
619
m_pHandler->Store(dset);
621
if (m_pModelo != NULL) {
622
OFString OFEstudioUId;
623
if (dset->findAndGetOFString(DCM_StudyInstanceUID, OFEstudioUId).good()) {
624
OFString OFPacienteUID;
625
std::string PacienteUID;
626
if (dset->findAndGetOFString(DCM_PatientID, OFPacienteUID).good()) {
627
PacienteUID.assign(OFPacienteUID.c_str());
630
OFString OFPacienteNombre;
631
std::string PacienteNombre;
632
if (dset->findAndGetOFString(DCM_PatientName, OFPacienteNombre).good()) {
633
PacienteNombre.assign(OFPacienteNombre.c_str());
636
OFString OFPacienteFechaNacimiento;
637
std::string PacienteFechaNacimiento;
639
if (dset->findAndGetOFString(DCM_PatientBirthDate, OFPacienteFechaNacimiento).good()) {
640
PacienteFechaNacimiento.assign(OFPacienteFechaNacimiento.c_str());
644
OFString OFPacienteSexo;
645
std::string PacienteSexo;
646
if (dset->findAndGetOFString(DCM_PatientSex, OFPacienteSexo).good()) {
647
PacienteSexo.assign(OFPacienteSexo.c_str());
650
const IModeloPaciente& paciente = m_pModelo->InsertarPaciente(PacienteUID, PacienteNombre, PacienteFechaNacimiento, PacienteSexo);
652
OFString OFEstudioUID;
653
std::string EstudioUID;
654
if (dset->findAndGetOFString(DCM_StudyInstanceUID, OFEstudioUID).good()) {
655
EstudioUID.assign(OFEstudioUID.c_str());
658
OFString OFEAccNumber;
659
std::string AccNumber;
660
if (dset->findAndGetOFString(DCM_AccessionNumber, OFEAccNumber).good()) {
661
AccNumber.assign(OFEAccNumber.c_str());
664
OFString OFEstudioDescripcion;
665
std::string EstudioDescripcion;
666
if (dset->findAndGetOFString(DCM_StudyDescription, OFEstudioDescripcion).good()) {
667
EstudioDescripcion.assign(OFEstudioDescripcion.c_str());
670
OFString OFEstudioModalidad;
671
std::string EstudioModalidad;
672
if (dset->findAndGetOFString(DCM_ModalitiesInStudy, OFEstudioModalidad).good()) {
673
EstudioModalidad.assign(OFEstudioModalidad.c_str());
676
OFString OFEstudioFecha;
677
std::string EstudioFecha;
678
if (dset->findAndGetOFString(DCM_StudyDate, OFEstudioFecha).good()) {
679
EstudioFecha.assign(OFEstudioFecha.c_str());
682
OFString OFEstudioHora;
683
std::string EstudioHora;
684
if (dset->findAndGetOFString(DCM_StudyTime, OFEstudioHora).good()) {
685
EstudioHora.assign(OFEstudioHora.c_str());
689
OFString OFEstudioDoctor;
690
std::string EstudioDoctor;
691
if (dset->findAndGetOFString(DCM_ReferringPhysicianName, OFEstudioDoctor).good()) {
692
EstudioDoctor.assign(OFEstudioDoctor.c_str());
695
m_pModelo->InsertarEstudio(paciente.GetUID(), EstudioUID, AccNumber, EstudioDescripcion, EstudioModalidad, EstudioFecha, EstudioHora, EstudioDoctor);
698
std::string SerieUID;
699
if (dset->findAndGetOFString(DCM_SeriesInstanceUID, OFSerieUID).good()) {
700
SerieUID.assign(OFSerieUID.c_str());
703
OFString OFSerieTipo;
704
std::string SerieTipo;
705
if (dset->findAndGetOFString(DCM_SeriesType, OFSerieTipo).good()) {
706
SerieTipo.assign(OFSerieTipo.c_str());
709
OFString OFSerieFecha;
710
std::string SerieFecha;
711
if (dset->findAndGetOFString(DCM_SeriesDate, OFSerieFecha).good()) {
712
SerieFecha.assign(OFSerieFecha.c_str());
715
OFString OFSerieHora;
716
std::string SerieHora;
717
if (dset->findAndGetOFString(DCM_SeriesTime, OFSerieHora).good()) {
718
SerieHora.assign(OFSerieHora.c_str());
721
OFString OFSerieDescripcion;
722
std::string SerieDescripcion;
723
if (dset->findAndGetOFString(DCM_SeriesDescription, OFSerieDescripcion).good()) {
724
SerieDescripcion.assign(OFSerieDescripcion.c_str());
727
OFString OFSerieNumero;
728
std::string SerieNumero;
729
if (dset->findAndGetOFString(DCM_NumberOfSeriesRelatedInstances, OFSerieNumero).good()) {
730
SerieNumero.assign(OFSerieNumero.c_str());
733
OFString OFSerieDoctor;
734
std::string SerieDoctor;
735
if (dset->findAndGetOFString(DCM_ReferringPhysicianName, OFSerieDoctor).good()) {
736
SerieDoctor.assign(OFSerieDoctor.c_str());
739
m_pModelo->InsertarSerie(EstudioUID, SerieUID, SerieTipo, SerieFecha, SerieHora, SerieDescripcion,SerieNumero,SerieDoctor);
741
OFString OFUIDImagen;
742
std::string UIDImagen;
743
if (dset->findAndGetOFString(DCM_SOPInstanceUID, OFUIDImagen).good()) {
744
UIDImagen.assign(OFUIDImagen.c_str());
745
m_pModelo->InsertarImagen(SerieUID,UIDImagen);
751
void GetAssociation::SetCallbackHandler(IStoreCallBack * handler) {
752
m_pHandler = handler;
755
float GetAssociation::TasaTransferencia(int bytesDescargados)
757
time_t nuevoInstante = time(NULL);
758
const double tiempo = difftime(nuevoInstante,m_medida.m_instante);
760
if(bytesDescargados > m_medida.bytesDescargados) {
761
const double bytesRecibidosPeriodo = bytesDescargados - m_medida.bytesDescargados;
762
m_medida.oldTasa = ( ((float)bytesRecibidosPeriodo/1024.0f)/tiempo );
763
m_medida.bytesDescargados = bytesDescargados;
764
m_medida.m_instante = nuevoInstante;
767
return m_medida.oldTasa;
770
void GetAssociation::ResetearMedida(bool clearTasa) {
771
m_medida.bytesDescargados = 0;
772
m_medida.m_instante = time(NULL);
774
m_medida.oldTasa=0.0f;