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

« back to all changes in this revision

Viewing changes to .pc/spelling.patch/src/cadxcore/main/controllers/dcmtk/dicomgetassociation.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-05-02 08:09:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110502080926-tfd00s81ak843xk3
Tags: 2.4.1.1-1
Initial release (Closes: #628106)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
*
 
3
*  $Id$
 
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
*/
 
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>
 
21
 
 
22
#include "istorecallback.h"
 
23
 
 
24
#include "dicomnetwork.h"
 
25
#include "dicomgetassociation.h"
 
26
 
 
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>
 
33
 
 
34
std::string GetAssociation::m_errorMessage = "";
 
35
 
 
36
GetAssociation::GetAssociation(const std::string& _ambitolog, IModeloDicom* pModelo) : FindAssociation(_ambitolog) {
 
37
        m_abstractSyntax = (char*) UID_GETStudyRootQueryRetrieveInformationModel;
 
38
        m_maxReceivePDULength = ASC_DEFAULTMAXPDU;
 
39
        m_pHandler = NULL;
 
40
        m_pModelo = pModelo;
 
41
        m_numeroImagenes=0;
 
42
        m_mensaje="";
 
43
        m_errorMessage = "";
 
44
        m_bytesDescargados = 0;
 
45
        m_wellKnownNumResults = 0;
 
46
}
 
47
 
 
48
GetAssociation::~GetAssociation() { }
 
49
 
 
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);
 
52
}
 
53
 
 
54
void GetAssociation::SetWellKnownNumResults(unsigned int numResults){
 
55
        m_wellKnownNumResults = numResults;
 
56
}
 
57
 
 
58
void GetAssociation::SetModelo(IModeloDicom* pModelo) {
 
59
        m_pModelo = pModelo;
 
60
}
 
61
 
 
62
CONDITION GetAssociation::SendObject(DcmDataset *dataset) {
 
63
        return getSCU(dataset);
 
64
}
 
65
 
 
66
void GetAssociation::SetStorageSOPClasses(const SOPClassList& SOPClasses)
 
67
{
 
68
        this->SOPClasses = SOPClasses;
 
69
}
 
70
 
 
71
void GetAssociation::OnAddPresentationContext(T_ASC_Parameters * params) {
 
72
 
 
73
        unsigned int pid = 1;
 
74
 
 
75
        CONDITION cond = ASC_addPresentationContext(params, pid, m_abstractSyntax, AllTransferSyntaxes, 3);
 
76
        if (cond.bad()) {
 
77
                LOG_ERROR(ambitolog, "Unable to add GETStudyRootQueryRetrieveInformationModel presentation context");
 
78
                return;
 
79
        }
 
80
 
 
81
        pid += 2;
 
82
 
 
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() ) {
 
86
 
 
87
                                for (unsigned int j = 0; pid <= 255 && j < AllTransferSyntaxesCount && cond.good(); j++) {
 
88
                                        cond = ASC_addPresentationContext(params, pid, dcmLongSCUStorageSOPClassUIDs[i], &AllTransferSyntaxes[j], 1);
 
89
                                        pid += 2;
 
90
                                }
 
91
                        }
 
92
                }
 
93
 
 
94
                if (pid >= 255) {
 
95
                        LOG_WARN("C-GET", "Too many PresentationContexts setted");
 
96
                }
 
97
        }
 
98
        else {
 
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);
 
101
                        pid += 2;                       
 
102
                }
 
103
                if (pid >= 255) {
 
104
                        LOG_WARN("C-GET", "Too many PresentationContexts setted");
 
105
                }
 
106
        }
 
107
}
 
108
 
 
109
static int
 
110
selectReadable(T_ASC_Association *assoc,
 
111
                                        T_ASC_Network *net, T_ASC_Association *subAssoc,
 
112
                                        T_DIMSE_BlockingMode blockMode, int timeout)
 
113
{
 
114
        T_ASC_Association *assocList[2];
 
115
        int assocCount = 0;
 
116
 
 
117
        if (net != NULL && subAssoc == NULL) {
 
118
                if (ASC_associationWaiting(net, 0)) {
 
119
                        /* association request waiting on network */
 
120
                        return 2;
 
121
                }
 
122
        }
 
123
        assocList[0] = assoc;
 
124
        assocCount = 1;
 
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 */
 
129
        } else {
 
130
                if (blockMode == DIMSE_BLOCKING) {
 
131
                        timeout = 10000;    /* a long time */
 
132
                }
 
133
        }
 
134
        if (!ASC_selectReadableAssociation(assocList, assocCount, timeout)) {
 
135
                /* none readable */
 
136
                return 0;
 
137
        }
 
138
        if (assocList[0] != NULL) {
 
139
                /* main association readable */
 
140
                return 1;
 
141
        }
 
142
        if (assocList[1] != NULL) {
 
143
                /* sub association readable */
 
144
                return 2;
 
145
        }
 
146
        /* should not be reached */
 
147
        return 0;
 
148
}
 
149
 
 
150
 
 
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,
 
158
                                                                        /* out */
 
159
                                                                        T_DIMSE_C_GetRSP * /*response*/, DcmDataset **statusDetail,
 
160
                                                                        DcmDataset **rspIds)
 
161
{
 
162
        T_DIMSE_Message req, rsp;
 
163
        DIC_US msgId;
 
164
        int responseCount = 0;
 
165
        T_ASC_Association *subAssoc = NULL;
 
166
        DIC_US status = STATUS_Pending;
 
167
 
 
168
        if (requestIdentifiers == NULL) return DIMSE_NULLKEY;
 
169
 
 
170
        bzero((char*)&req, sizeof(req));
 
171
        bzero((char*)&rsp, sizeof(rsp));
 
172
 
 
173
        req.CommandField = DIMSE_C_GET_RQ;
 
174
        request->DataSetType = DIMSE_DATASET_PRESENT;
 
175
        req.msg.CGetRQ = *request;
 
176
 
 
177
        msgId = request->MessageID;
 
178
 
 
179
        LOG_DEBUG("C-GET", "Accepted presID " << (int)presID);
 
180
 
 
181
        OFCondition cond = DIMSE_sendMessageUsingMemoryData(assoc, presID, &req,
 
182
                NULL, requestIdentifiers,
 
183
                NULL, NULL);
 
184
        if (cond != EC_Normal) {
 
185
                return cond;
 
186
        }
 
187
 
 
188
        /* receive responses */
 
189
 
 
190
        while (cond == EC_Normal && status == STATUS_Pending) {
 
191
 
 
192
                /* if user wants, multiplex between net/subAssoc
 
193
                * and responses over main assoc.
 
194
                */
 
195
                switch (selectReadable(assoc, getassoc->GetNetwork()->GetDcmtkNet(), subAssoc, blockMode, timeout)) {
 
196
                  case 0:
 
197
                          /* none are readble, timeout */
 
198
                          if (blockMode == DIMSE_BLOCKING) {
 
199
                                  continue;       /* continue with while loop */
 
200
                          } else {
 
201
                                  return DIMSE_NODATAAVAILABLE;
 
202
                          }
 
203
                          /* break; */ // never reached after continue or return.
 
204
                  case 1:
 
205
                          /* main association readable */
 
206
                          break;
 
207
                  case 2:
 
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
 
212
                }
 
213
 
 
214
                bzero((char*)&rsp, sizeof(rsp));
 
215
 
 
216
                cond = DIMSE_receiveCommand(assoc, blockMode, timeout, &presID,
 
217
                        &rsp, statusDetail);
 
218
                if (cond != EC_Normal) {
 
219
                        return cond;
 
220
                }
 
221
 
 
222
                {
 
223
                        OFString str;
 
224
                        DIMSE_dumpMessage(str, rsp, DIMSE_INCOMING);
 
225
                        LOG_DEBUG("C-GET", "Command received" << std::endl << str.c_str());
 
226
                }
 
227
 
 
228
                switch (rsp.CommandField){
 
229
                case DIMSE_C_STORE_RQ:
 
230
                        {
 
231
                                if (rsp.msg.CStoreRQ.DataSetType != DIMSE_DATASET_NULL) {
 
232
                                        cond = getassoc->storeSCP(assoc, &rsp, presID);
 
233
                                        if (cond != EC_Normal) {
 
234
                                                return cond;
 
235
                                        }
 
236
                                        else {
 
237
                                                ;
 
238
                                        }
 
239
                                }
 
240
                        }
 
241
                        break;
 
242
                case DIMSE_C_GET_RSP:
 
243
                        {
 
244
                                if (rsp.msg.CGetRSP.MessageIDBeingRespondedTo != msgId)
 
245
                                {
 
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());
 
249
                                }
 
250
 
 
251
                                status = rsp.msg.CGetRSP.DimseStatus;
 
252
                                responseCount++;
 
253
 
 
254
                                switch (status) {
 
255
                case STATUS_Pending:
 
256
                        if (*statusDetail != NULL) {
 
257
                                DCMNET_WARN(DIMSE_warn_str(assoc) << "getUser: Pending with statusDetail, ignoring detail");
 
258
                                delete *statusDetail;
 
259
                                *statusDetail = NULL;
 
260
                        }
 
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");
 
264
                        }
 
265
 
 
266
                        break;
 
267
 
 
268
                default:
 
269
 
 
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) {
 
274
                                        return cond;
 
275
                                }
 
276
                        }
 
277
                        break;
 
278
                                }
 
279
                        }
 
280
                        break;
 
281
                default:
 
282
                        {
 
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());
 
286
                        }
 
287
                        break;
 
288
                }
 
289
        }
 
290
 
 
291
 
 
292
        /* do remaining sub-association work, we may receive a non-pending
 
293
        * status before the sub-association has cleaned up.
 
294
        */
 
295
        while (subAssoc != NULL) {
 
296
                getassoc->subOpCallback(getassoc, getassoc->GetNetwork()->GetDcmtkNet(), &subAssoc);
 
297
        }
 
298
 
 
299
 
 
300
        return cond;
 
301
}
 
302
 
 
303
 
 
304
CONDITION GetAssociation::getSCU(DcmDataset *pdset) {
 
305
        CONDITION cond;
 
306
        T_ASC_PresentationContextID presId;
 
307
        T_DIMSE_C_GetRQ req;
 
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;
 
315
 
 
316
        if (pdset == NULL) {
 
317
                LOG_ERROR(ambitolog, "Dataset nulo en getSCU");
 
318
                return DIMSE_NULLKEY;
 
319
        }
 
320
 
 
321
        {
 
322
                OFString str;
 
323
                ASC_dumpParameters(str, assoc->params, ASC_ASSOC_AC);
 
324
                LOG_DEBUG("C-GET", str.c_str());
 
325
 
 
326
        }
 
327
 
 
328
        //sopClass = m_abstractSyntaxMove;
 
329
        sopClass = m_abstractSyntax;
 
330
 
 
331
        // which presentation context should be used
 
332
        presId = ASC_findAcceptedPresentationContextID(assoc, sopClass);
 
333
 
 
334
        if (presId == 0) {
 
335
                return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
 
336
        }
 
337
 
 
338
        callbackData.assoc = assoc;
 
339
        callbackData.presId = presId;
 
340
        callbackData.pCaller = this;
 
341
 
 
342
        storeCallbackData.assoc = assoc;
 
343
        //storeCallbackData.presId = presId;
 
344
        storeCallbackData.pCaller = this;
 
345
 
 
346
        req.MessageID = msgId;
 
347
        strcpy(req.AffectedSOPClassUID, sopClass);
 
348
        req.Priority = DIMSE_PRIORITY_HIGH;
 
349
        req.DataSetType = DIMSE_DATASET_PRESENT;
 
350
 
 
351
        ResetearMedida(true);
 
352
        m_numeroImagenes=0;
 
353
 
 
354
        {
 
355
                OFString str;
 
356
                DIMSE_dumpMessage(str, req, DIMSE_OUTGOING, pdset, presId);
 
357
                LOG_DEBUG("C-GET", str.c_str());
 
358
        }
 
359
 
 
360
 
 
361
        cond = MDIMSE_getUser(
 
362
                assoc,
 
363
                this,
 
364
                presId,
 
365
                &req,
 
366
                pdset,
 
367
                DIMSE_BLOCKING,
 
368
                0,
 
369
                &rsp, &statusDetail, &rspIds);
 
370
 
 
371
        if (cond.bad()) {
 
372
                LOG_DEBUG(ambitolog, "DIMSE_getUser(): " << cond.text() );
 
373
        }
 
374
        if (statusDetail != NULL) {
 
375
                LOG_DEBUG(ambitolog, "DIMSE_getUser(): Estado: " << std::endl << DumpDataset(statusDetail));
 
376
                delete statusDetail;
 
377
        }
 
378
 
 
379
        if (rspIds != NULL) {
 
380
 
 
381
                delete rspIds;
 
382
        }
 
383
 
 
384
        if(m_errorMessage != "")
 
385
        {
 
386
                throw GIL::DICOM::PACSException(m_errorMessage, "Adquisition");
 
387
        }
 
388
 
 
389
        return cond;
 
390
}
 
391
 
 
392
void GetAssociation::getCallback(void * /*callbackData*/, T_DIMSE_C_GetRQ * /*request*/, int /*responseCount*/, T_DIMSE_C_GetRSP * /*response*/)
 
393
{
 
394
 
 
395
}
 
396
 
 
397
void GetAssociation::subOpCallback(void *pCaller, T_ASC_Network *aNet, T_ASC_Association **subAssoc) {
 
398
        GetAssociation* caller = (GetAssociation*) pCaller;
 
399
 
 
400
        if (caller->GetNetwork() == NULL) {
 
401
                return;
 
402
        }
 
403
 
 
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);
 
408
 
 
409
        if (*subAssoc == NULL) {
 
410
                // negotiate association
 
411
                LOG_DEBUG(caller->ambitolog, "Aceptando subAsociaci�n");
 
412
                caller->acceptSubAssoc(aNet, subAssoc);
 
413
        }
 
414
        else {
 
415
                // be a service class provider
 
416
                LOG_DEBUG(caller->ambitolog, "Invocando subOp SCP");
 
417
                caller->subOpSCP(subAssoc);
 
418
        }
 
419
}
 
420
 
 
421
CONDITION GetAssociation::acceptSubAssoc(T_ASC_Network* /*aNet*/, T_ASC_Association** /*assoc*/) {
 
422
        CONDITION cond = ASC_NORMAL;
 
423
 
 
424
        return cond;
 
425
 
 
426
}
 
427
 
 
428
CONDITION GetAssociation::subOpSCP(T_ASC_Association **subAssoc) {
 
429
        T_DIMSE_Message msg;
 
430
        T_ASC_PresentationContextID presID;
 
431
 
 
432
        /* just in case */
 
433
        if (!ASC_dataWaiting(*subAssoc, 0)) {
 
434
                LOG_TRACE(ambitolog, "No hay datos pendientes");
 
435
                return DIMSE_NODATAAVAILABLE;
 
436
        }
 
437
 
 
438
        OFCondition cond = DIMSE_receiveCommand(*subAssoc, DIMSE_BLOCKING, 0, &presID, &msg, NULL);
 
439
 
 
440
        if (cond.bad()) {
 
441
 
 
442
        }
 
443
 
 
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);
 
449
                                break;
 
450
                        case DIMSE_C_ECHO_RQ:
 
451
                                LOG_TRACE(ambitolog, "Invocando C-ECHO_RQ");
 
452
                                cond = echoSCP(*subAssoc, &msg, presID);
 
453
                                break;
 
454
                        default:
 
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;
 
457
                                break;
 
458
                }
 
459
        }
 
460
 
 
461
        // clean up on association termination
 
462
        if (cond == DUL_PEERREQUESTEDRELEASE) {
 
463
                cond = ASC_acknowledgeRelease(*subAssoc);
 
464
                ASC_dropSCPAssociation(*subAssoc);
 
465
                ASC_destroyAssociation(subAssoc);
 
466
                return cond;
 
467
        }
 
468
        else if (cond == DUL_PEERABORTEDASSOCIATION) {
 
469
                LOG_ERROR(ambitolog, "El PACS remoto abort� la asociaci�n"  << cond.text());
 
470
        }
 
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);
 
475
        }
 
476
 
 
477
        if (cond != EC_Normal) {
 
478
                ASC_dropAssociation(*subAssoc);
 
479
                ASC_destroyAssociation(subAssoc);
 
480
        }
 
481
        return cond;
 
482
}
 
483
 
 
484
CONDITION GetAssociation::storeSCP(T_ASC_Association *assoc, T_DIMSE_Message *msg, T_ASC_PresentationContextID presID) {
 
485
        CONDITION cond;
 
486
        T_DIMSE_C_StoreRQ* req;
 
487
        DcmDataset *dset = new DcmDataset;
 
488
 
 
489
        req = &msg->msg.CStoreRQ;
 
490
 
 
491
        StoreCallbackInfo callbackData;
 
492
        callbackData.dataset = dset;
 
493
        callbackData.pCaller = this;
 
494
        callbackData.assoc = assoc;
 
495
 
 
496
        cond = DIMSE_storeProvider(assoc, presID, req, (char *) NULL, 1,
 
497
                &dset, storeSCPCallback, (void*) & callbackData,
 
498
                DIMSE_BLOCKING, 0);
 
499
 
 
500
        delete dset;
 
501
        return cond;
 
502
}
 
503
 
 
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) {
 
505
        DIC_UI sopClass;
 
506
        DIC_UI sopInstance;
 
507
 
 
508
        StoreCallbackInfo *cbdata = (StoreCallbackInfo*) callbackData;
 
509
        GetAssociation* caller = cbdata->pCaller;
 
510
 
 
511
        float partial = 0.0f;
 
512
        float step = 0.0f;
 
513
 
 
514
        if (caller->m_wellKnownNumResults > 0 ) {               
 
515
                step = 1.0f / (float) caller->m_wellKnownNumResults;
 
516
                partial = (float)caller->m_numeroImagenes * step;
 
517
        }
 
518
        else {
 
519
                ;
 
520
        }
 
521
 
 
522
        if (progress->state == DIMSE_StoreBegin) {
 
523
                wxString msg;
 
524
                if (caller->m_wellKnownNumResults > 0) {
 
525
                        msg = wxString::Format(_("Downloading file %d/%d"), caller->m_numeroImagenes + 1, caller->m_wellKnownNumResults );
 
526
                }
 
527
                else {
 
528
                        msg = wxString::Format(_("Downloading file %d"), caller->m_numeroImagenes + 1 );
 
529
                }
 
530
                caller->m_mensaje = std::string(msg.ToUTF8());
 
531
                LOG_DEBUG(caller->ambitolog, caller->m_mensaje);
 
532
 
 
533
                if (!caller->NotificarProgreso((float) partial, caller->m_mensaje) ) {
 
534
                        rsp->DimseStatus = STATUS_STORE_Refused_OutOfResources;
 
535
                        caller->Stop();
 
536
                        ASC_releaseAssociation(caller->assoc);
 
537
                        LOG_INFO(caller->ambitolog, "Operation canceled by user");
 
538
                        return;
 
539
                }
 
540
 
 
541
                caller->m_bytesDescargados += progress->totalBytes;
 
542
                GNC::GCS::Permisos::EstadoPermiso estado = GNC::GCS::ControladorPermisos::Instance()->Get("core.pacs.limits", "study_size");
 
543
                if (estado) {
 
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;
 
547
                                caller->Stop();
 
548
                                ASC_releaseAssociation(caller->assoc);
 
549
                                return;
 
550
                        }
 
551
                }
 
552
        }
 
553
 
 
554
 
 
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 );
 
560
                ostr.precision(2);
 
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) )
 
564
                {
 
565
                        rsp->DimseStatus = STATUS_STORE_Refused_OutOfResources;
 
566
                        OFCondition cond = ASC_releaseAssociation(cbdata->assoc);
 
567
                        return;
 
568
                }
 
569
        }
 
570
 
 
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();
 
576
 
 
577
                /* could save the image somewhere else, put it in database, etc */
 
578
                rsp->DimseStatus = STATUS_Success;
 
579
 
 
580
                if ((imageDataSet) && (*imageDataSet)) {
 
581
                        // do not duplicate the dataset, let the user do this
 
582
                        // if he wants to
 
583
                        caller->OnResponseReceived(cbdata->dataset);
 
584
                }
 
585
 
 
586
                /* should really check the image to make sure it is consistent,
 
587
                * that its sopClass and sopInstance correspond with those in
 
588
                * the request.
 
589
                */
 
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");
 
595
                        }
 
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 << ")");
 
599
                        }
 
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 << ")");
 
603
                        }
 
604
                }
 
605
        }
 
606
}
 
607
 
 
608
CONDITION GetAssociation::echoSCP(T_ASC_Association *assoc, T_DIMSE_Message *msg, T_ASC_PresentationContextID presID) {
 
609
        CONDITION cond;
 
610
 
 
611
        // the echo succeeded !!
 
612
        cond = DIMSE_sendEchoResponse(assoc, presID, &msg->msg.CEchoRQ, STATUS_Success, NULL);
 
613
 
 
614
        return cond;
 
615
}
 
616
 
 
617
void GetAssociation::OnResponseReceived(DcmDataset* dset) {
 
618
        if (m_pHandler != NULL) {
 
619
                m_pHandler->Store(dset);
 
620
        }
 
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());
 
628
                        }
 
629
 
 
630
                        OFString OFPacienteNombre;
 
631
                        std::string PacienteNombre;
 
632
                        if (dset->findAndGetOFString(DCM_PatientName, OFPacienteNombre).good()) {
 
633
                                PacienteNombre.assign(OFPacienteNombre.c_str());
 
634
                        }
 
635
 
 
636
                        OFString OFPacienteFechaNacimiento;
 
637
                        std::string PacienteFechaNacimiento;
 
638
 
 
639
                        if (dset->findAndGetOFString(DCM_PatientBirthDate, OFPacienteFechaNacimiento).good()) {
 
640
                                PacienteFechaNacimiento.assign(OFPacienteFechaNacimiento.c_str());
 
641
                        }
 
642
 
 
643
 
 
644
                        OFString OFPacienteSexo;
 
645
                        std::string PacienteSexo;
 
646
                        if (dset->findAndGetOFString(DCM_PatientSex, OFPacienteSexo).good()) {
 
647
                                PacienteSexo.assign(OFPacienteSexo.c_str());
 
648
                        }
 
649
 
 
650
                        const IModeloPaciente& paciente = m_pModelo->InsertarPaciente(PacienteUID, PacienteNombre, PacienteFechaNacimiento, PacienteSexo);
 
651
 
 
652
                        OFString OFEstudioUID;
 
653
                        std::string EstudioUID;
 
654
                        if (dset->findAndGetOFString(DCM_StudyInstanceUID, OFEstudioUID).good()) {
 
655
                                EstudioUID.assign(OFEstudioUID.c_str());
 
656
                        }
 
657
 
 
658
                        OFString OFEAccNumber;
 
659
                        std::string AccNumber;
 
660
                        if (dset->findAndGetOFString(DCM_AccessionNumber, OFEAccNumber).good()) {
 
661
                                AccNumber.assign(OFEAccNumber.c_str());
 
662
                        }
 
663
 
 
664
                        OFString OFEstudioDescripcion;
 
665
                        std::string EstudioDescripcion;
 
666
                        if (dset->findAndGetOFString(DCM_StudyDescription, OFEstudioDescripcion).good()) {
 
667
                                EstudioDescripcion.assign(OFEstudioDescripcion.c_str());
 
668
                        }
 
669
 
 
670
                        OFString OFEstudioModalidad;
 
671
                        std::string EstudioModalidad;
 
672
                        if (dset->findAndGetOFString(DCM_ModalitiesInStudy, OFEstudioModalidad).good()) {
 
673
                                EstudioModalidad.assign(OFEstudioModalidad.c_str());
 
674
                        }
 
675
 
 
676
                        OFString OFEstudioFecha;
 
677
                        std::string EstudioFecha;
 
678
                        if (dset->findAndGetOFString(DCM_StudyDate, OFEstudioFecha).good()) {
 
679
                                EstudioFecha.assign(OFEstudioFecha.c_str());
 
680
                        }
 
681
 
 
682
                        OFString OFEstudioHora;
 
683
                        std::string EstudioHora;
 
684
                        if (dset->findAndGetOFString(DCM_StudyTime, OFEstudioHora).good()) {
 
685
                                EstudioHora.assign(OFEstudioHora.c_str());
 
686
                        }
 
687
 
 
688
 
 
689
                        OFString OFEstudioDoctor;
 
690
                        std::string EstudioDoctor;
 
691
                        if (dset->findAndGetOFString(DCM_ReferringPhysicianName, OFEstudioDoctor).good()) {
 
692
                                EstudioDoctor.assign(OFEstudioDoctor.c_str());
 
693
                        }
 
694
 
 
695
                        m_pModelo->InsertarEstudio(paciente.GetUID(), EstudioUID, AccNumber, EstudioDescripcion, EstudioModalidad, EstudioFecha, EstudioHora, EstudioDoctor);
 
696
 
 
697
                        OFString OFSerieUID;
 
698
                        std::string SerieUID;
 
699
                        if (dset->findAndGetOFString(DCM_SeriesInstanceUID, OFSerieUID).good()) {
 
700
                                SerieUID.assign(OFSerieUID.c_str());
 
701
                        }
 
702
 
 
703
                        OFString OFSerieTipo;
 
704
                        std::string SerieTipo;
 
705
                        if (dset->findAndGetOFString(DCM_SeriesType, OFSerieTipo).good()) {
 
706
                                SerieTipo.assign(OFSerieTipo.c_str());
 
707
                        }
 
708
 
 
709
                        OFString OFSerieFecha;
 
710
                        std::string SerieFecha;
 
711
                        if (dset->findAndGetOFString(DCM_SeriesDate, OFSerieFecha).good()) {
 
712
                                SerieFecha.assign(OFSerieFecha.c_str());
 
713
                        }
 
714
 
 
715
                        OFString OFSerieHora;
 
716
                        std::string SerieHora;
 
717
                        if (dset->findAndGetOFString(DCM_SeriesTime, OFSerieHora).good()) {
 
718
                                SerieHora.assign(OFSerieHora.c_str());
 
719
                        }
 
720
 
 
721
                        OFString OFSerieDescripcion;
 
722
                        std::string SerieDescripcion;
 
723
                        if (dset->findAndGetOFString(DCM_SeriesDescription, OFSerieDescripcion).good()) {
 
724
                                SerieDescripcion.assign(OFSerieDescripcion.c_str());
 
725
                        }
 
726
 
 
727
                        OFString OFSerieNumero;
 
728
                        std::string SerieNumero;
 
729
                        if (dset->findAndGetOFString(DCM_NumberOfSeriesRelatedInstances, OFSerieNumero).good()) {
 
730
                                SerieNumero.assign(OFSerieNumero.c_str());
 
731
                        }
 
732
 
 
733
                        OFString OFSerieDoctor;
 
734
                        std::string SerieDoctor;
 
735
                        if (dset->findAndGetOFString(DCM_ReferringPhysicianName, OFSerieDoctor).good()) {
 
736
                                SerieDoctor.assign(OFSerieDoctor.c_str());
 
737
                        }
 
738
 
 
739
                        m_pModelo->InsertarSerie(EstudioUID, SerieUID, SerieTipo, SerieFecha, SerieHora, SerieDescripcion,SerieNumero,SerieDoctor);
 
740
 
 
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);
 
746
                        }
 
747
                }
 
748
        }
 
749
}
 
750
 
 
751
void GetAssociation::SetCallbackHandler(IStoreCallBack * handler) {
 
752
        m_pHandler = handler;
 
753
}
 
754
 
 
755
float GetAssociation::TasaTransferencia(int bytesDescargados)
 
756
{
 
757
        time_t nuevoInstante = time(NULL);
 
758
        const double tiempo = difftime(nuevoInstante,m_medida.m_instante);
 
759
        if(tiempo>0.5){
 
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;
 
765
                }
 
766
        }
 
767
        return m_medida.oldTasa;
 
768
}
 
769
 
 
770
void GetAssociation::ResetearMedida(bool clearTasa) {
 
771
        m_medida.bytesDescargados = 0;
 
772
        m_medida.m_instante = time(NULL);
 
773
        if(clearTasa) {
 
774
                m_medida.oldTasa=0.0f;
 
775
        }
 
776
}
 
777