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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2013-07-21 11:58:53 UTC
  • mfrom: (7.2.1 sid)
  • Revision ID: package-import@ubuntu.com-20130721115853-44e7n1xujqglu78e
Tags: 3.4.0.928.29+dfsg-1
* 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
 
 *  
3
 
 *  $Id: dicomcustomassociation.cpp $
4
 
 *  Ginkgo CADx Project
5
 
 *
6
 
 *  Copyright 2008-12 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
 
 */
 
2
*  
 
3
*  $Id: dicomcustomassociation.cpp $
 
4
*  Ginkgo CADx Project
 
5
*
 
6
*  Copyright 2008-12 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
13
 
14
14
#include <wx/string.h>
15
15
#include <wx/intl.h>
25
25
 
26
26
#include "dicomcustomassociation.h"
27
27
#include "helpercompresion.h"
 
28
#include <main/controllers/pacscontroller.h>
28
29
 
29
30
#include <api/dicom/dcmdictionary.h>
30
31
//#include <main/controllers/dicommanager.h>
49
50
 
50
51
void DIMSE_printNStatusString(std::ostream& dumpStream, int status)
51
52
{
52
 
  switch(status)
53
 
  {
54
 
    case STATUS_Success:
55
 
      dumpStream << "0x0000: Success";
56
 
      break;
57
 
    case STATUS_N_Cancel:
58
 
      dumpStream << "0xFE00: Cancel";
59
 
      break;
60
 
    case STATUS_N_AttributeListError:
61
 
      dumpStream << "0x0107: Attribute list error";
62
 
      break;
63
 
    case STATUS_N_SOPClassNotSupported:
64
 
      dumpStream << "0x0122: SOP class not supported";
65
 
      break;
66
 
    case STATUS_N_ClassInstanceConflict:
67
 
      dumpStream << "0x0119: Class/instance conflict";
68
 
      break;
69
 
    case STATUS_N_DuplicateSOPInstance:
70
 
      dumpStream << "0x0111: Duplicate SOP instance";
71
 
      break;
72
 
    case STATUS_N_DuplicateInvocation:
73
 
      dumpStream << "0x0210: Duplicate invocation";
74
 
      break;
75
 
    case STATUS_N_InvalidArgumentValue:
76
 
      dumpStream << "0x0115: Invalid argument value";
77
 
      break;
78
 
    case STATUS_N_InvalidAttributeValue:
79
 
      dumpStream << "0x0106: Invalid attribute value";
80
 
      break;
81
 
    case STATUS_N_InvalidObjectInstance:
82
 
      dumpStream << "0x0117: Invalid object instance";
83
 
      break;
84
 
    case STATUS_N_MissingAttribute:
85
 
      dumpStream << "0x0120: Missing attribute";
86
 
      break;
87
 
    case STATUS_N_MissingAttributeValue:
88
 
      dumpStream << "0x0121: Missing attribute value";
89
 
      break;
90
 
    case STATUS_N_MistypedArgument:
91
 
      dumpStream << "0x0212: Mistyped argument";
92
 
      break;
93
 
    case STATUS_N_NoSuchArgument:
94
 
      dumpStream << "0x0114: No such argument";
95
 
      break;
96
 
    case STATUS_N_NoSuchAttribute:
97
 
      dumpStream << "0x0105: No such attribute";
98
 
      break;
99
 
    case STATUS_N_NoSuchEventType:
100
 
      dumpStream << "0x0113: No such event type";
101
 
      break;
102
 
    case STATUS_N_NoSuchObjectInstance:
103
 
      dumpStream << "0x0112: No such object instance";
104
 
      break;
105
 
    case STATUS_N_NoSuchSOPClass:
106
 
      dumpStream << "0x0118: No such SOP class";
107
 
      break;
108
 
    case STATUS_N_ProcessingFailure:
109
 
      dumpStream << "0x0110: Processing failure";
110
 
      break;
111
 
    case STATUS_N_ResourceLimitation:
112
 
      dumpStream << "0x0213: Resource limitation";
113
 
      break;
114
 
    case STATUS_N_UnrecognizedOperation:
115
 
      dumpStream << "0x0211: Unrecognized operation";
116
 
      break;
117
 
    default:
118
 
      dumpStream << "0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4)
119
 
          << status << ": Unknown Status Code";
120
 
      break;
121
 
  }
 
53
        switch(status)
 
54
        {
 
55
        case STATUS_Success:
 
56
                dumpStream << "0x0000: Success";
 
57
                break;
 
58
        case STATUS_N_Cancel:
 
59
                dumpStream << "0xFE00: Cancel";
 
60
                break;
 
61
        case STATUS_N_AttributeListError:
 
62
                dumpStream << "0x0107: Attribute list error";
 
63
                break;
 
64
        case STATUS_N_SOPClassNotSupported:
 
65
                dumpStream << "0x0122: SOP class not supported";
 
66
                break;
 
67
        case STATUS_N_ClassInstanceConflict:
 
68
                dumpStream << "0x0119: Class/instance conflict";
 
69
                break;
 
70
        case STATUS_N_DuplicateSOPInstance:
 
71
                dumpStream << "0x0111: Duplicate SOP instance";
 
72
                break;
 
73
        case STATUS_N_DuplicateInvocation:
 
74
                dumpStream << "0x0210: Duplicate invocation";
 
75
                break;
 
76
        case STATUS_N_InvalidArgumentValue:
 
77
                dumpStream << "0x0115: Invalid argument value";
 
78
                break;
 
79
        case STATUS_N_InvalidAttributeValue:
 
80
                dumpStream << "0x0106: Invalid attribute value";
 
81
                break;
 
82
        case STATUS_N_InvalidObjectInstance:
 
83
                dumpStream << "0x0117: Invalid object instance";
 
84
                break;
 
85
        case STATUS_N_MissingAttribute:
 
86
                dumpStream << "0x0120: Missing attribute";
 
87
                break;
 
88
        case STATUS_N_MissingAttributeValue:
 
89
                dumpStream << "0x0121: Missing attribute value";
 
90
                break;
 
91
        case STATUS_N_MistypedArgument:
 
92
                dumpStream << "0x0212: Mistyped argument";
 
93
                break;
 
94
        case STATUS_N_NoSuchArgument:
 
95
                dumpStream << "0x0114: No such argument";
 
96
                break;
 
97
        case STATUS_N_NoSuchAttribute:
 
98
                dumpStream << "0x0105: No such attribute";
 
99
                break;
 
100
        case STATUS_N_NoSuchEventType:
 
101
                dumpStream << "0x0113: No such event type";
 
102
                break;
 
103
        case STATUS_N_NoSuchObjectInstance:
 
104
                dumpStream << "0x0112: No such object instance";
 
105
                break;
 
106
        case STATUS_N_NoSuchSOPClass:
 
107
                dumpStream << "0x0118: No such SOP class";
 
108
                break;
 
109
        case STATUS_N_ProcessingFailure:
 
110
                dumpStream << "0x0110: Processing failure";
 
111
                break;
 
112
        case STATUS_N_ResourceLimitation:
 
113
                dumpStream << "0x0213: Resource limitation";
 
114
                break;
 
115
        case STATUS_N_UnrecognizedOperation:
 
116
                dumpStream << "0x0211: Unrecognized operation";
 
117
                break;
 
118
        default:
 
119
                dumpStream << "0x" << STD_NAMESPACE hex << STD_NAMESPACE setfill('0') << STD_NAMESPACE setw(4)
 
120
                        << status << ": Unknown Status Code";
 
121
                break;
 
122
        }
122
123
}
123
124
 
124
125
CustomAssociation::CustomAssociation(void* connectionKey, const std::string& ambitolog, GNC::IProxyNotificadorProgreso* pNotificadorProgreso) :
125
 
                Association(ambitolog), GIL::DICOM::ICustomAssociation()
 
126
        Association(ambitolog), GIL::DICOM::ICustomAssociation()
126
127
{
127
128
        if (connectionKey == NULL) {
128
129
                LOG_ERROR(ambitolog, "NULL Connection key");
136
137
}
137
138
 
138
139
CustomAssociation::~CustomAssociation() {
139
 
        
 
140
 
140
141
}
141
 
bool CustomAssociation::Connect(const std::string& /*serverId*/, const std::string& /*local_aet*/)
 
142
bool CustomAssociation::Connect(const std::string& serverId, const std::string& local_aet)
142
143
{
143
 
        /*
144
 
        CONDITION status = DIMSE_NORMAL;
145
 
        
146
 
        //1. Open Association
147
 
        
 
144
        DicomServerList* listaServidores = DicomServerList::Instance();
 
145
        m_server = listaServidores->GetServer(serverId);
 
146
        if (!m_server.IsValid()) {
 
147
                LOG_ERROR("C-MOVE/C-GET", "Invalid server");
 
148
                return false;
 
149
        }
 
150
 
148
151
        if (!Net->Initiallized()) {
149
152
                Net->InitializeNetwork(GetTimeout(), GetRole(), GetAcceptorPort());
150
153
        }
151
 
        
 
154
 
152
155
        Create(
153
 
                        server->AET,
154
 
                        server->HostName,
155
 
                        server->Port,
156
 
                        local_aet
157
 
        );
158
 
        
159
 
        SetNotificadorProgreso(m_pNotificadorProgreso);
160
 
 
161
 
        LOG_DEBUG(ambitolog, "Connecting: AET = " << server->AET << ", Host = " << server->HostName << ", Port = " << server->Port << ", Local AET = " << local_aet << ", PDU = " << server->PDU);
162
 
        CONDITION r = Association::Connect(Net, server->PDU);
163
 
        
164
 
        CONDITION c = ECC_Normal;
165
 
        
166
 
        //Uint16 rstatus;
167
 
 
168
 
        if (r.good() == true) {
169
 
                
170
 
                // 3. N-CREATE (UPS)
171
 
                
172
 
                DcmDataset* response;
173
 
                DcmDataset attrs;
174
 
                DcmElement* e = NULL;
175
 
                DcmSequenceOfItems* seq = NULL;
176
 
                DcmItem* item = NULL;
177
 
                
178
 
                e = newDicomElement(DCM_UnifiedProcedureStepState);
179
 
                e->putString("SCHEDULED");
180
 
                attrs.insert(e);
181
 
 
182
 
                e = newDicomElement(DCM_ScheduledProcedureStepPriority);
183
 
                e->putString("MEDIUM");
184
 
                attrs.insert(e);
185
 
 
186
 
                e = newDicomElement(DCM_WorklistLabel);
187
 
                e->putString("worklist test");
188
 
                attrs.insert(e);
189
 
 
190
 
                e = newDicomElement(DCM_ProcedureStepLabel);
191
 
                e->putString("test step");
192
 
                attrs.insert(e);
193
 
 
194
 
                e = newDicomElement(DCM_CommentsOnTheScheduledProcedureStep);
195
 
                e->putString("comentarios");
196
 
                attrs.insert(e);
197
 
 
198
 
                e = newDicomElement(DCM_ScheduledProcedureStepStartDateTime);
199
 
                e->putString("20120416114500");
200
 
                attrs.insert(e);
201
 
 
202
 
                e = newDicomElement(DCM_ExpectedCompletionDateTime);
203
 
                e->putString("20120416144000");
204
 
                attrs.insert(e);
205
 
 
206
 
                std::string strTmp;
207
 
                e = newDicomElement(DCM_StudyInstanceUID);
208
 
                if (parameters.getTag(GKDCM_StudyInstanceUID, strTmp)) {
209
 
                        e->putString(strTmp.c_str());
210
 
                }
211
 
                attrs.insert(e);
212
 
 
213
 
                e = newDicomElement(DCM_PatientName);
214
 
                if (parameters.getTag(GKDCM_PatientName, strTmp)) {
215
 
                        e->putString(strTmp.c_str());
216
 
                }
217
 
                attrs.insert(e);
218
 
 
219
 
                e = newDicomElement(DCM_PatientID);
220
 
                if (parameters.getTag(GKDCM_PatientID, strTmp)) {
221
 
                        e->putString(strTmp.c_str());
222
 
                }
223
 
                attrs.insert(e);
224
 
 
225
 
                e = newDicomElement(DCM_AdmissionID);
226
 
                if (parameters.getTag(GKDCM_AdmissionID, strTmp)) {
227
 
                        e->putString(strTmp.c_str());
228
 
                }
229
 
                attrs.insert(e);
230
 
 
231
 
                e = newDicomElement(DCM_TransactionUID);
232
 
                attrs.insert(e);
233
 
 
234
 
                OFString upsSopInstanceUID;
235
 
                c = createRQ(UID_UnifiedProcedureStepPushSOPClass, upsSopInstanceUID, &attrs, rstatus, response);
236
 
 
237
 
 
238
 
 
239
 
                DcmDataset actionInformation;
240
 
                e = newDicomElement(DCM_TransactionUID);
241
 
 
242
 
                e->putString("1.2.40.0.13.1.1.10.231.162.70.20100921082909711.32774.1");
243
 
                actionInformation.insert(e);
244
 
 
245
 
                e = newDicomElement(DCM_UnifiedProcedureStepState);
246
 
                e->putString("IN PROGRESS");
247
 
                actionInformation.insert(e);
248
 
 
249
 
                OFCondition resultStatus = actionRQ(UID_UnifiedProcedureStepPullSOPClass, upsSopInstanceUID.c_str(), 1, &actionInformation, rstatus, response);
250
 
 
251
 
                
252
 
                if (c.good()) {
253
 
                }
254
 
                else {
255
 
                        return c;
256
 
                }
257
 
                return r;
258
 
        }
259
 
        else {
 
156
                m_server->AET,
 
157
                m_server->HostName,
 
158
                m_server->Port,
 
159
                local_aet
 
160
                );
 
161
 
 
162
        CONDITION r = Association::Connect(Net, m_server->PDU);
 
163
 
 
164
        if (r.bad()) {
260
165
                LOG_ERROR(ambitolog, "Error al conectar:" << r.text());
261
166
                Drop();
262
167
                Destroy();
263
168
                throw GIL::DICOM::PACSException(r.text());
264
169
        }
265
 
        
266
 
        if (!c.good()) {
267
 
                LOG_ERROR(ambitolog, "Error al enviar objeto: " << c.text());
268
 
                Drop();
269
 
                Destroy();
270
 
                throw GIL::DICOM::PACSException(c.text());
271
 
        }
272
 
        
273
 
        return status;
274
 
        */
275
 
        return false;
 
170
        return r.good();
276
171
}
277
172
 
278
173
void CustomAssociation::OnAddPresentationContext(T_ASC_Parameters* params) {
279
 
        OFCondition cond = EC_Normal;
280
 
        
281
 
        const char* transferSyntaxes[3];
282
 
        int transferSyntaxCount = 0;
283
 
        
284
 
        /* gLocalByteOrder is defined in dcxfer.h */
285
 
        if (gLocalByteOrder == EBO_LittleEndian) {
286
 
                /* we are on a little endian machine */
287
 
                transferSyntaxes[0] = UID_LittleEndianExplicitTransferSyntax;
288
 
                transferSyntaxes[1] = UID_BigEndianExplicitTransferSyntax;
 
174
        unsigned int pid = 1;
 
175
        OFCondition cond;
 
176
        if (SOPClasses.size() > 0) {
 
177
                GIL::DICOM::TransferSyntaxList tsList;
 
178
                tsList.push_back(UID_LittleEndianImplicitTransferSyntax);
 
179
                
 
180
                for (GIL::DICOM::SOPClassList::const_iterator itSopClass = SOPClasses.begin(); pid <= 255 && itSopClass != SOPClasses.end() && cond.good(); ++itSopClass) {
 
181
                        for (GIL::DICOM::TransferSyntaxList::const_iterator itTS = tsList.begin(); pid <= 255 && itTS != tsList.end() && cond.good(); ++itTS) {
 
182
                                const char* ts[] = {(*itTS).c_str()};
 
183
                                cond = ASC_addPresentationContext(params, pid, (*itSopClass).c_str(), ts, 1);
 
184
                                pid += 2;
 
185
                        }
 
186
 
 
187
                }
 
188
 
 
189
                if (pid >= 255) {
 
190
                        LOG_WARN("C-GET", "Too many PresentationContexts setted");
 
191
                }
 
192
        } else {        
 
193
                LOG_WARN("C-GET", "NO PresentationContexts setted");
 
194
        }
 
195
}
 
196
 
 
197
void CustomAssociation::dumpNMessage(T_DIMSE_Message &msg, DcmItem *dataset, OFBool outgoing)
 
198
{
 
199
        OFString str;
 
200
        if (outgoing) {
 
201
                DIMSE_dumpMessage(str, msg, DIMSE_OUTGOING, dataset);
289
202
        } else {
290
 
                /* we are on a big endian machine */
291
 
                transferSyntaxes[0] = UID_BigEndianExplicitTransferSyntax;
292
 
                transferSyntaxes[1] = UID_LittleEndianExplicitTransferSyntax;
 
203
                DIMSE_dumpMessage(str, msg, DIMSE_INCOMING, dataset);
293
204
        }
294
 
        transferSyntaxes[2] = UID_LittleEndianImplicitTransferSyntax;
295
 
        transferSyntaxCount = 3;
296
 
        
297
 
        if (cond.good()) cond = ASC_addPresentationContext(params, 1, UID_UnifiedProcedureStepPushSOPClass, transferSyntaxes, transferSyntaxCount);
298
 
        if (cond.good()) cond = ASC_addPresentationContext(params, 3, UID_UnifiedProcedureStepPullSOPClass, transferSyntaxes, transferSyntaxCount);
299
 
}
300
 
 
301
 
void CustomAssociation::dumpNMessage(T_DIMSE_Message &msg, DcmItem *dataset, OFBool outgoing)
302
 
{
303
 
    OFString str;
304
 
    if (outgoing) {
305
 
        DIMSE_dumpMessage(str, msg, DIMSE_OUTGOING, dataset);
306
 
    } else {
307
 
        DIMSE_dumpMessage(str, msg, DIMSE_INCOMING, dataset);
308
 
    }
309
 
    LOG_DEBUG(ambitolog, str);
 
205
        LOG_DEBUG(ambitolog, str);
310
206
}
311
207
 
312
208
OFCondition CustomAssociation::sendNRequest(
313
 
    T_ASC_PresentationContextID presId,
314
 
    T_DIMSE_Message &request,
315
 
    DcmDataset *rqDataSet,
316
 
    T_DIMSE_Message &response,
317
 
    DcmDataset* &statusDetail,
318
 
    DcmDataset* &rspDataset)
 
209
        T_ASC_PresentationContextID presId,
 
210
        T_DIMSE_Message &request,
 
211
        DcmDataset *rqDataSet,
 
212
        T_DIMSE_Message &response,
 
213
        DcmDataset* &statusDetail,
 
214
        DcmDataset* &rspDataset)
319
215
{
320
 
    OFCondition cond = EC_Normal;
321
 
    T_DIMSE_Command expectedResponse;
322
 
    DIC_US expectedMessageID=0;
323
 
    if (assoc == NULL)
324
 
    {
325
 
      return DIMSE_ILLEGALASSOCIATION;
326
 
    }
327
 
 
328
 
    T_DIMSE_DataSetType datasetType = DIMSE_DATASET_NULL;
329
 
    if (rqDataSet && (rqDataSet->card() > 0)) datasetType = DIMSE_DATASET_PRESENT;
330
 
    
331
 
    switch(request.CommandField)
332
 
    {
333
 
      case DIMSE_N_GET_RQ:
334
 
        request.msg.NGetRQ.DataSetType = datasetType;
335
 
        expectedResponse = DIMSE_N_GET_RSP;
336
 
        expectedMessageID = request.msg.NGetRQ.MessageID;
337
 
        break;
338
 
      case DIMSE_N_SET_RQ:
339
 
        request.msg.NSetRQ.DataSetType = datasetType;
340
 
        expectedResponse = DIMSE_N_SET_RSP;
341
 
        expectedMessageID = request.msg.NSetRQ.MessageID;
342
 
        break;
343
 
      case DIMSE_N_ACTION_RQ:
344
 
        request.msg.NActionRQ.DataSetType = datasetType;
345
 
        expectedResponse = DIMSE_N_ACTION_RSP;
346
 
        expectedMessageID = request.msg.NActionRQ.MessageID;
347
 
        break;
348
 
      case DIMSE_N_CREATE_RQ:
349
 
        request.msg.NCreateRQ.DataSetType = datasetType;
350
 
        expectedResponse = DIMSE_N_CREATE_RSP;
351
 
        expectedMessageID = request.msg.NCreateRQ.MessageID;
352
 
        break;
353
 
      case DIMSE_N_DELETE_RQ:
354
 
        request.msg.NDeleteRQ.DataSetType = datasetType;
355
 
        expectedResponse = DIMSE_N_DELETE_RSP;
356
 
        expectedMessageID = request.msg.NDeleteRQ.MessageID;
357
 
        break;
358
 
      default:
359
 
        return DIMSE_BADCOMMANDTYPE;
360
 
        /* break; */
361
 
    }
362
 
 
363
 
    dumpNMessage(request, rqDataSet, OFTrue);
364
 
    cond = DIMSE_sendMessageUsingMemoryData(assoc, presId, &request, NULL, rqDataSet, NULL, NULL);
365
 
    if (cond.bad()) return cond;
366
 
 
367
 
    T_ASC_PresentationContextID thisPresId;
368
 
    T_DIMSE_Message eventReportRsp;
369
 
    DIC_US eventReportStatus;
370
 
    do
371
 
    {
372
 
        thisPresId = presId;
373
 
        statusDetail = NULL;
374
 
        cond = DIMSE_receiveCommand(assoc, blockMode, this->m_timeout, &thisPresId, &response, &statusDetail);
375
 
        if (cond.bad()) return cond;
376
 
 
377
 
        if (response.CommandField == DIMSE_N_EVENT_REPORT_RQ)
378
 
        {
379
 
          /* handle N-EVENT-REPORT-RQ */
380
 
          rspDataset = NULL;
381
 
          if (response.msg.NEventReportRQ.DataSetType == DIMSE_DATASET_PRESENT)
382
 
          {
383
 
            cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
384
 
            if (cond.bad()) return cond;
385
 
          }  
386
 
          dumpNMessage(response, rspDataset, OFFalse);
387
 
          // call event handler if registered
388
 
          eventReportStatus = STATUS_Success;
389
 
          if (eventHandler) eventReportStatus = eventHandler->handleEvent(response.msg.NEventReportRQ, rspDataset, statusDetail);
390
 
          if (rspDataset) delete rspDataset;
391
 
          rspDataset = NULL;
392
 
          if (statusDetail) delete statusDetail;
393
 
          statusDetail = NULL;
394
 
          
395
 
          // send back N-EVENT-REPORT-RSP */
396
 
          eventReportRsp.CommandField = DIMSE_N_EVENT_REPORT_RSP;
397
 
          eventReportRsp.msg.NEventReportRSP.MessageIDBeingRespondedTo = response.msg.NEventReportRQ.MessageID;
398
 
          eventReportRsp.msg.NEventReportRSP.EventTypeID = response.msg.NEventReportRQ.EventTypeID;
399
 
          eventReportRsp.msg.NEventReportRSP.DimseStatus = eventReportStatus;
400
 
          eventReportRsp.msg.NEventReportRSP.DataSetType = DIMSE_DATASET_NULL;
401
 
          eventReportRsp.msg.NEventReportRSP.opts = O_NEVENTREPORT_EVENTTYPEID;
402
 
          eventReportRsp.msg.NEventReportRSP.AffectedSOPClassUID[0] = 0;
403
 
          eventReportRsp.msg.NEventReportRSP.AffectedSOPInstanceUID[0] = 0;
404
 
          dumpNMessage(eventReportRsp, NULL, OFTrue);
405
 
          cond = DIMSE_sendMessageUsingMemoryData(assoc, thisPresId, &eventReportRsp, NULL, NULL, NULL, NULL);
406
 
          if (cond.bad()) return cond;
407
 
        } else {
408
 
          /* No N-EVENT-REPORT-RQ. Check if this message is what we expected */
409
 
          if (response.CommandField != expectedResponse)
410
 
          {
411
 
            char buf1[256];
412
 
            sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
413
 
            return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
414
 
          }
415
 
          T_DIMSE_DataSetType responseDataset = DIMSE_DATASET_NULL;
416
 
          DIC_US responseMessageID = 0;
417
 
          /** change request to response */     
418
 
          switch(expectedResponse)
419
 
          {
420
 
            case DIMSE_N_GET_RSP:
421
 
              responseDataset = response.msg.NGetRSP.DataSetType;
422
 
              responseMessageID = response.msg.NGetRSP.MessageIDBeingRespondedTo;
423
 
              break;
424
 
            case DIMSE_N_SET_RSP:
425
 
              responseDataset = response.msg.NSetRSP.DataSetType;
426
 
              responseMessageID = response.msg.NSetRSP.MessageIDBeingRespondedTo;
427
 
              break;
428
 
            case DIMSE_N_ACTION_RSP:
429
 
              responseDataset = response.msg.NActionRSP.DataSetType;
430
 
              responseMessageID = response.msg.NActionRSP.MessageIDBeingRespondedTo;
431
 
              break;
432
 
            case DIMSE_N_CREATE_RSP:
433
 
              responseDataset = response.msg.NCreateRSP.DataSetType;
434
 
              responseMessageID = response.msg.NCreateRSP.MessageIDBeingRespondedTo;
435
 
              break;
436
 
            case DIMSE_N_DELETE_RSP:
437
 
              responseDataset = response.msg.NDeleteRSP.DataSetType;
438
 
              responseMessageID = response.msg.NDeleteRSP.MessageIDBeingRespondedTo;
439
 
              break;
440
 
            default:
441
 
              {
442
 
                char buf1[256];
443
 
                sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
444
 
                return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
445
 
              }
446
 
              /* break; */
447
 
          }
448
 
          if (responseMessageID != expectedMessageID)
449
 
          {
450
 
            char buf1[256];
451
 
            sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
452
 
            return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
453
 
          }
454
 
          rspDataset = NULL;
455
 
          if (responseDataset == DIMSE_DATASET_PRESENT)
456
 
          {
457
 
            cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
458
 
            if (cond.bad()) return cond;
459
 
          }
460
 
          dumpNMessage(response, rspDataset, OFFalse);
461
 
        }
462
 
    } while (response.CommandField == DIMSE_N_EVENT_REPORT_RQ);
463
 
    return EC_Normal;
 
216
        OFCondition cond = EC_Normal;
 
217
        T_DIMSE_Command expectedResponse;
 
218
        DIC_US expectedMessageID=0;
 
219
        if (assoc == NULL)
 
220
        {
 
221
                return DIMSE_ILLEGALASSOCIATION;
 
222
        }
 
223
 
 
224
        T_DIMSE_DataSetType datasetType = DIMSE_DATASET_NULL;
 
225
        if (rqDataSet && (rqDataSet->card() > 0)) datasetType = DIMSE_DATASET_PRESENT;
 
226
 
 
227
        switch(request.CommandField)
 
228
        {
 
229
        case DIMSE_N_GET_RQ:
 
230
                request.msg.NGetRQ.DataSetType = datasetType;
 
231
                expectedResponse = DIMSE_N_GET_RSP;
 
232
                expectedMessageID = request.msg.NGetRQ.MessageID;
 
233
                break;
 
234
        case DIMSE_N_SET_RQ:
 
235
                request.msg.NSetRQ.DataSetType = datasetType;
 
236
                expectedResponse = DIMSE_N_SET_RSP;
 
237
                expectedMessageID = request.msg.NSetRQ.MessageID;
 
238
                break;
 
239
        case DIMSE_N_ACTION_RQ:
 
240
                request.msg.NActionRQ.DataSetType = datasetType;
 
241
                expectedResponse = DIMSE_N_ACTION_RSP;
 
242
                expectedMessageID = request.msg.NActionRQ.MessageID;
 
243
                break;
 
244
        case DIMSE_N_CREATE_RQ:
 
245
                request.msg.NCreateRQ.DataSetType = datasetType;
 
246
                expectedResponse = DIMSE_N_CREATE_RSP;
 
247
                expectedMessageID = request.msg.NCreateRQ.MessageID;
 
248
                break;
 
249
        case DIMSE_N_DELETE_RQ:
 
250
                request.msg.NDeleteRQ.DataSetType = datasetType;
 
251
                expectedResponse = DIMSE_N_DELETE_RSP;
 
252
                expectedMessageID = request.msg.NDeleteRQ.MessageID;
 
253
                break;
 
254
        default:
 
255
                return DIMSE_BADCOMMANDTYPE;
 
256
                /* break; */
 
257
        }
 
258
 
 
259
        dumpNMessage(request, rqDataSet, OFTrue);
 
260
        cond = DIMSE_sendMessageUsingMemoryData(assoc, presId, &request, NULL, rqDataSet, NULL, NULL);
 
261
        if (cond.bad()) return cond;
 
262
 
 
263
        T_ASC_PresentationContextID thisPresId;
 
264
        T_DIMSE_Message eventReportRsp;
 
265
        DIC_US eventReportStatus;
 
266
        do
 
267
        {
 
268
                thisPresId = presId;
 
269
                statusDetail = NULL;
 
270
                cond = DIMSE_receiveCommand(assoc, blockMode, this->m_timeout, &thisPresId, &response, &statusDetail);
 
271
                if (cond.bad()) return cond;
 
272
 
 
273
                if (response.CommandField == DIMSE_N_EVENT_REPORT_RQ)
 
274
                {
 
275
                        /* handle N-EVENT-REPORT-RQ */
 
276
                        rspDataset = NULL;
 
277
                        if (response.msg.NEventReportRQ.DataSetType == DIMSE_DATASET_PRESENT)
 
278
                        {
 
279
                                cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
 
280
                                if (cond.bad()) return cond;
 
281
                        }  
 
282
                        dumpNMessage(response, rspDataset, OFFalse);
 
283
                        // call event handler if registered
 
284
                        eventReportStatus = STATUS_Success;
 
285
                        if (eventHandler) eventReportStatus = eventHandler->handleEvent(response.msg.NEventReportRQ, rspDataset, statusDetail);
 
286
                        if (rspDataset) delete rspDataset;
 
287
                        rspDataset = NULL;
 
288
                        if (statusDetail) delete statusDetail;
 
289
                        statusDetail = NULL;
 
290
 
 
291
                        // send back N-EVENT-REPORT-RSP */
 
292
                        eventReportRsp.CommandField = DIMSE_N_EVENT_REPORT_RSP;
 
293
                        eventReportRsp.msg.NEventReportRSP.MessageIDBeingRespondedTo = response.msg.NEventReportRQ.MessageID;
 
294
                        eventReportRsp.msg.NEventReportRSP.EventTypeID = response.msg.NEventReportRQ.EventTypeID;
 
295
                        eventReportRsp.msg.NEventReportRSP.DimseStatus = eventReportStatus;
 
296
                        eventReportRsp.msg.NEventReportRSP.DataSetType = DIMSE_DATASET_NULL;
 
297
                        eventReportRsp.msg.NEventReportRSP.opts = O_NEVENTREPORT_EVENTTYPEID;
 
298
                        eventReportRsp.msg.NEventReportRSP.AffectedSOPClassUID[0] = 0;
 
299
                        eventReportRsp.msg.NEventReportRSP.AffectedSOPInstanceUID[0] = 0;
 
300
                        dumpNMessage(eventReportRsp, NULL, OFTrue);
 
301
                        cond = DIMSE_sendMessageUsingMemoryData(assoc, thisPresId, &eventReportRsp, NULL, NULL, NULL, NULL);
 
302
                        if (cond.bad()) return cond;
 
303
                } else {
 
304
                        /* No N-EVENT-REPORT-RQ. Check if this message is what we expected */
 
305
                        if (response.CommandField != expectedResponse)
 
306
                        {
 
307
                                char buf1[256];
 
308
                                sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
 
309
                                return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
 
310
                        }
 
311
                        T_DIMSE_DataSetType responseDataset = DIMSE_DATASET_NULL;
 
312
                        DIC_US responseMessageID = 0;
 
313
                        /** change request to response */     
 
314
                        switch(expectedResponse)
 
315
                        {
 
316
                        case DIMSE_N_GET_RSP:
 
317
                                responseDataset = response.msg.NGetRSP.DataSetType;
 
318
                                responseMessageID = response.msg.NGetRSP.MessageIDBeingRespondedTo;
 
319
                                break;
 
320
                        case DIMSE_N_SET_RSP:
 
321
                                responseDataset = response.msg.NSetRSP.DataSetType;
 
322
                                responseMessageID = response.msg.NSetRSP.MessageIDBeingRespondedTo;
 
323
                                break;
 
324
                        case DIMSE_N_ACTION_RSP:
 
325
                                responseDataset = response.msg.NActionRSP.DataSetType;
 
326
                                responseMessageID = response.msg.NActionRSP.MessageIDBeingRespondedTo;
 
327
                                break;
 
328
                        case DIMSE_N_CREATE_RSP:
 
329
                                responseDataset = response.msg.NCreateRSP.DataSetType;
 
330
                                responseMessageID = response.msg.NCreateRSP.MessageIDBeingRespondedTo;
 
331
                                break;
 
332
                        case DIMSE_N_DELETE_RSP:
 
333
                                responseDataset = response.msg.NDeleteRSP.DataSetType;
 
334
                                responseMessageID = response.msg.NDeleteRSP.MessageIDBeingRespondedTo;
 
335
                                break;
 
336
                        default:
 
337
                                {
 
338
                                        char buf1[256];
 
339
                                        sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
 
340
                                        return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
 
341
                                }
 
342
                                /* break; */
 
343
                        }
 
344
                        if (responseMessageID != expectedMessageID)
 
345
                        {
 
346
                                char buf1[256];
 
347
                                sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
 
348
                                return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
 
349
                        }
 
350
                        rspDataset = NULL;
 
351
                        if (responseDataset == DIMSE_DATASET_PRESENT)
 
352
                        {
 
353
                                cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
 
354
                                if (cond.bad()) return cond;
 
355
                        }
 
356
                        dumpNMessage(response, rspDataset, OFFalse);
 
357
                }
 
358
        } while (response.CommandField == DIMSE_N_EVENT_REPORT_RQ);
 
359
        return EC_Normal;
464
360
}    
465
361
 
466
 
bool CustomAssociation::createRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, const GIL::DICOM::DicomDataset& /*attributeListIn*/,  int& /*status*/, GNC::GCS::Ptr<GIL::DICOM::DicomDataset>& /*attributeListOut*/)
467
 
/*
468
 
OFCondition CustomAssociation::createRQ(
469
 
    const char *sopclassUID, 
470
 
    OFString& sopinstanceUID, 
471
 
    DcmDataset *attributeListIn, 
472
 
    Uint16& status, 
473
 
    DcmDataset* &attributeListOut)
474
 
*/
475
 
{
476
 
        /*
477
 
  if (assoc == NULL)
478
 
  {
479
 
    return DIMSE_ILLEGALASSOCIATION;
480
 
  }
481
 
  if (sopclassUID==NULL)
482
 
  {
483
 
    return DIMSE_NULLKEY;
484
 
  }
485
 
 
486
 
  T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
487
 
  if (presCtx == 0)
488
 
  {
489
 
    return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
490
 
  }  
491
 
 
492
 
  T_DIMSE_Message request;
493
 
  T_DIMSE_Message response;
494
 
  DcmDataset *statusDetail = NULL;
495
 
 
496
 
  // construct N-CREATE-RQ
497
 
  request.CommandField = DIMSE_N_CREATE_RQ;
498
 
  request.msg.NCreateRQ.MessageID = assoc->nextMsgID++;
499
 
  strcpy(request.msg.NCreateRQ.AffectedSOPClassUID, sopclassUID);
500
 
  if (sopinstanceUID.size() > 0)
501
 
  {
502
 
    strcpy(request.msg.NCreateRQ.AffectedSOPInstanceUID, sopinstanceUID.c_str());
503
 
    request.msg.NCreateRQ.opts = O_NCREATE_AFFECTEDSOPINSTANCEUID;
504
 
  } else {
505
 
    request.msg.NCreateRQ.AffectedSOPInstanceUID[0] = 0;
506
 
    request.msg.NCreateRQ.opts = 0;
507
 
  }
508
 
  
509
 
  OFCondition cond = sendNRequest(presCtx, request, attributeListIn, response, statusDetail, attributeListOut);
510
 
  if (statusDetail) delete statusDetail;
511
 
  if (cond.good()) 
512
 
  {
513
 
    status = response.msg.NCreateRSP.DimseStatus;
514
 
         if (status != 0) {
515
 
                 LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
516
 
                 std::ostringstream ostr;
517
 
                 ostr << "Error sending create rq status: "<< status << " details: ";
518
 
                 DIMSE_printNStatusString(ostr, status);
519
 
                 throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
520
 
         }
521
 
    // if response contains SOP Instance UID, copy it.
522
 
    if (response.msg.NCreateRSP.opts & O_NCREATE_AFFECTEDSOPINSTANCEUID)
523
 
    {
524
 
      sopinstanceUID = response.msg.NCreateRSP.AffectedSOPInstanceUID;
525
 
    }
526
 
  }
527
 
  return cond;
528
 
  */
529
 
        return false;
530
 
}
531
 
 
532
 
 
533
 
 
534
 
 
535
 
bool CustomAssociation::setRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, const GIL::DICOM::DicomDataset& /*modificationList*/, int& /*status*/, GNC::GCS::Ptr<GIL::DICOM::DicomDataset>& /*attributeListOut*/)
536
 
/*
537
 
OFCondition CustomAssociation::setRQ(
538
 
    const char *sopclassUID, 
539
 
    const char *sopinstanceUID, 
540
 
    DcmDataset *modificationList, 
541
 
    Uint16& status, 
542
 
    DcmDataset* &attributeListOut)
543
 
*/
544
 
{
545
 
        /*
546
 
  if (assoc == NULL)
547
 
  {
548
 
    return DIMSE_ILLEGALASSOCIATION;
549
 
  }
550
 
  if ((sopclassUID==NULL)||(sopinstanceUID==NULL)||(modificationList==NULL))
551
 
  {
552
 
    return DIMSE_NULLKEY;
553
 
  }
554
 
 
555
 
  T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
556
 
  if (presCtx == 0)
557
 
  {
558
 
    return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
559
 
  }  
560
 
 
561
 
  T_DIMSE_Message request;
562
 
  T_DIMSE_Message response;
563
 
  DcmDataset *statusDetail = NULL;
564
 
 
565
 
  // construct N-SET-RQ
566
 
  request.CommandField = DIMSE_N_SET_RQ;
567
 
  request.msg.NSetRQ.MessageID = assoc->nextMsgID++;
568
 
  strcpy(request.msg.NSetRQ.RequestedSOPClassUID, sopclassUID);
569
 
  strcpy(request.msg.NSetRQ.RequestedSOPInstanceUID, sopinstanceUID);
570
 
   
571
 
  OFCondition cond = sendNRequest(presCtx, request, modificationList, response, statusDetail, attributeListOut);
572
 
  if (cond.good()) status = response.msg.NSetRSP.DimseStatus;
573
 
  if (status != 0) {
574
 
                 LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
575
 
                 std::ostringstream ostr;
576
 
                 ostr << "Error sending create rq status: "<< status << " details: ";
577
 
                 DIMSE_printNStatusString(ostr, status);
578
 
                 throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
579
 
  }
580
 
  if (statusDetail) delete statusDetail;
581
 
  return cond;   
582
 
  */
583
 
        return false;
584
 
}
585
 
 
586
 
bool CustomAssociation::getRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, const int* /*attributeIdentifierList*/, unsigned long /*numShorts*/, int& /*status*/,  GNC::GCS::Ptr<GIL::DICOM::DicomDataset>& /*attributeListOut*/)
587
 
/*
588
 
OFCondition CustomAssociation::getRQ(
589
 
    const char *sopclassUID, 
590
 
    const char *sopinstanceUID, 
591
 
    const Uint16 *attributeIdentifierList,
592
 
    ssize_t numShorts,
593
 
    Uint16& status, 
594
 
    DcmDataset* &attributeListOut)
595
 
*/
596
 
{
597
 
        /*
598
 
  if (assoc == NULL)
599
 
  {
600
 
    return DIMSE_ILLEGALASSOCIATION;
601
 
  }
602
 
  if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
603
 
  {
604
 
    return DIMSE_NULLKEY;
605
 
  }
606
 
 
607
 
  T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
608
 
  if (presCtx == 0)
609
 
  {
610
 
    return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
611
 
  }  
612
 
 
613
 
  T_DIMSE_Message request;
614
 
  T_DIMSE_Message response;
615
 
  DcmDataset *statusDetail = NULL;
616
 
 
617
 
  // construct N-GET-RQ
618
 
  request.CommandField = DIMSE_N_GET_RQ;
619
 
  request.msg.NGetRQ.MessageID = assoc->nextMsgID++;
620
 
  strcpy(request.msg.NGetRQ.RequestedSOPClassUID, sopclassUID);
621
 
  strcpy(request.msg.NGetRQ.RequestedSOPInstanceUID, sopinstanceUID);
622
 
  request.msg.NGetRQ.ListCount = 0;
623
 
  if (attributeIdentifierList) request.msg.NGetRQ.ListCount = (int)numShorts;
624
 
  request.msg.NGetRQ.AttributeIdentifierList = (DIC_US *)attributeIdentifierList;
625
 
   
626
 
  OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
627
 
  if (cond.good()) status = response.msg.NGetRSP.DimseStatus;
628
 
  if (status != 0) {
629
 
         LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
630
 
         std::ostringstream ostr;
631
 
         ostr << "Error sending create rq status: "<< status << " details: ";
632
 
         DIMSE_printNStatusString(ostr, status);
633
 
         throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
634
 
  }
635
 
  if (statusDetail) delete statusDetail;
636
 
  return cond;   
637
 
  */
638
 
        return false;
639
 
}
640
 
 
641
 
bool CustomAssociation::actionRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, int /*actionTypeID*/, const GIL::DICOM::DicomDataset& /*actionInformation*/, int& /*status*/,  GNC::GCS::Ptr<GIL::DICOM::DicomDataset>& /*attributeListOut*/)
642
 
/*
643
 
OFCondition CustomAssociation::actionRQ(
644
 
    const char *sopclassUID, 
645
 
    const char *sopinstanceUID, 
646
 
    Uint16 actionTypeID, 
647
 
    DcmDataset *actionInformation,
648
 
    Uint16& status, 
649
 
    DcmDataset* &actionReply)
650
 
        */
651
 
{
652
 
        /*
653
 
  if (assoc == NULL)
654
 
  {
655
 
    return DIMSE_ILLEGALASSOCIATION;
656
 
  }
657
 
  if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
658
 
  {
659
 
    return DIMSE_NULLKEY;
660
 
  }
661
 
 
662
 
  T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
663
 
  if (presCtx == 0)
664
 
  {
665
 
    return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
666
 
  }  
667
 
 
668
 
  T_DIMSE_Message request;
669
 
  T_DIMSE_Message response;
670
 
  DcmDataset *statusDetail = NULL;
671
 
 
672
 
  // construct N-ACTION-RQ
673
 
  request.CommandField = DIMSE_N_ACTION_RQ;
674
 
  request.msg.NActionRQ.MessageID = assoc->nextMsgID++;
675
 
  strcpy(request.msg.NActionRQ.RequestedSOPClassUID, sopclassUID);
676
 
  strcpy(request.msg.NActionRQ.RequestedSOPInstanceUID, sopinstanceUID);
677
 
  request.msg.NActionRQ.ActionTypeID = (DIC_US)actionTypeID;
678
 
   ////////TODO: EST� FALLANDO
679
 
  OFCondition cond = sendNRequest(presCtx, request, actionInformation, response, statusDetail, actionReply);
680
 
  if (cond.good()) status = response.msg.NActionRSP.DimseStatus;
681
 
  if (status != 0) {
682
 
                LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
 
362
bool CustomAssociation::createRQ( const std::string& sopclassUID, const GIL::DICOM::DicomDataset& attributeListIn,  int& status, std::string& affectedSopinstanceUID)
 
363
{
 
364
        if (assoc == NULL)
 
365
        {
 
366
                LOG_ERROR(ambitolog, DIMSE_ILLEGALASSOCIATION.text());
 
367
                return false;
 
368
        }
 
369
        
 
370
 
 
371
        T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID.c_str());
 
372
        if (presCtx == 0)
 
373
        {
 
374
                LOG_ERROR(ambitolog, DIMSE_NOVALIDPRESENTATIONCONTEXTID.text());
 
375
                return false;
 
376
        }  
 
377
 
 
378
        T_DIMSE_Message request;
 
379
        T_DIMSE_Message response;
 
380
        DcmDataset *statusDetail = NULL;
 
381
 
 
382
        // construct N-CREATE-RQ
 
383
        request.CommandField = DIMSE_N_CREATE_RQ;
 
384
        request.msg.NCreateRQ.MessageID = assoc->nextMsgID++;
 
385
        strcpy(request.msg.NCreateRQ.AffectedSOPClassUID, sopclassUID.c_str());
 
386
        request.msg.NCreateRQ.AffectedSOPInstanceUID[0] = 0;
 
387
        request.msg.NCreateRQ.opts = 0;
 
388
        
 
389
        DcmDataset inAttr;
 
390
        DcmDataset* outAttr;
 
391
        GIL::DICOM::PACSController::Instance()->FillInQuery(attributeListIn, &inAttr, m_server);
 
392
 
 
393
        OFCondition cond = sendNRequest(presCtx, request, &inAttr, response, statusDetail, outAttr);
 
394
        if (statusDetail) {
 
395
                delete statusDetail;
 
396
                statusDetail = NULL;
 
397
        }
 
398
        if (cond.good()) 
 
399
        {
 
400
                status = response.msg.NCreateRSP.DimseStatus;
 
401
                if (status != 0) {
 
402
                        LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
 
403
                        std::ostringstream ostr;
 
404
                        ostr << "Error sending create rq status: "<< status << " details: ";
 
405
                        DIMSE_printNStatusString(ostr, status);
 
406
                        throw GIL::DICOM::PACSException(ostr.str(), "GIL::DICOMAssociation");
 
407
                }
 
408
                // if response contains SOP Instance UID, copy it.
 
409
                if (response.msg.NCreateRSP.opts & O_NCREATE_AFFECTEDSOPINSTANCEUID)
 
410
                {
 
411
                        affectedSopinstanceUID = response.msg.NCreateRSP.AffectedSOPInstanceUID;
 
412
                }
 
413
        }
 
414
        return cond.good();
 
415
}
 
416
 
 
417
 
 
418
 
 
419
 
 
420
bool CustomAssociation::setRQ( const std::string& sopclassUID, const std::string& sopinstanceUID, const GIL::DICOM::DicomDataset& modificationList, int& status)
 
421
{
 
422
        if (assoc == NULL)
 
423
        {
 
424
                LOG_ERROR(ambitolog, DIMSE_ILLEGALASSOCIATION.text());
 
425
                return false;
 
426
        }
 
427
        
 
428
 
 
429
        T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID.c_str());
 
430
        if (presCtx == 0)
 
431
        {
 
432
                LOG_ERROR(ambitolog, DIMSE_NOVALIDPRESENTATIONCONTEXTID.text());
 
433
                return false;
 
434
        }  
 
435
 
 
436
        T_DIMSE_Message request;
 
437
        T_DIMSE_Message response;
 
438
        DcmDataset *statusDetail = NULL;
 
439
 
 
440
        // construct N-CREATE-RQ
 
441
        request.CommandField = DIMSE_N_SET_RQ;
 
442
        request.msg.NSetRQ.MessageID = assoc->nextMsgID++;
 
443
        strcpy(request.msg.NSetRQ.RequestedSOPClassUID, sopclassUID.c_str());
 
444
        strcpy(request.msg.NSetRQ.RequestedSOPInstanceUID, sopinstanceUID.c_str());
 
445
        
 
446
        DcmDataset inAttr;
 
447
        DcmDataset* outAttr;
 
448
        GIL::DICOM::PACSController::Instance()->FillInQuery(modificationList, &inAttr, m_server);
 
449
 
 
450
        OFCondition cond = sendNRequest(presCtx, request, &inAttr, response, statusDetail, outAttr);
 
451
        if (cond.good()) status = response.msg.NSetRSP.DimseStatus;
 
452
        if (status != 0) {
 
453
                LOG_ERROR(ambitolog, "Error sending nset rq status: "<< status);
683
454
                std::ostringstream ostr;
684
 
                ostr << "Error sending create rq status: "<< status << " details: ";
 
455
                ostr << "Error sending nset rq status: "<< status << " details: ";
685
456
                DIMSE_printNStatusString(ostr, status);
686
457
                throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
687
 
  }
688
 
  if (statusDetail) delete statusDetail;
689
 
  return cond;   
690
 
  */
691
 
         return false;
 
458
        }
 
459
        if (statusDetail) delete statusDetail;
 
460
        return cond.good();   
 
461
}
 
462
 
 
463
bool CustomAssociation::getRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, const int* /*attributeIdentifierList*/, unsigned long /*numShorts*/, int& /*status*/,  GNC::GCS::Ptr<GIL::DICOM::DicomDataset>& /*attributeListOut*/)
 
464
        /*
 
465
        OFCondition CustomAssociation::getRQ(
 
466
        const char *sopclassUID, 
 
467
        const char *sopinstanceUID, 
 
468
        const Uint16 *attributeIdentifierList,
 
469
        ssize_t numShorts,
 
470
        Uint16& status, 
 
471
        DcmDataset* &attributeListOut)
 
472
        */
 
473
{
 
474
        /*
 
475
        if (assoc == NULL)
 
476
        {
 
477
        return DIMSE_ILLEGALASSOCIATION;
 
478
        }
 
479
        if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
 
480
        {
 
481
        return DIMSE_NULLKEY;
 
482
        }
 
483
 
 
484
        T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
 
485
        if (presCtx == 0)
 
486
        {
 
487
        return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
 
488
        }  
 
489
 
 
490
        T_DIMSE_Message request;
 
491
        T_DIMSE_Message response;
 
492
        DcmDataset *statusDetail = NULL;
 
493
 
 
494
        // construct N-GET-RQ
 
495
        request.CommandField = DIMSE_N_GET_RQ;
 
496
        request.msg.NGetRQ.MessageID = assoc->nextMsgID++;
 
497
        strcpy(request.msg.NGetRQ.RequestedSOPClassUID, sopclassUID);
 
498
        strcpy(request.msg.NGetRQ.RequestedSOPInstanceUID, sopinstanceUID);
 
499
        request.msg.NGetRQ.ListCount = 0;
 
500
        if (attributeIdentifierList) request.msg.NGetRQ.ListCount = (int)numShorts;
 
501
        request.msg.NGetRQ.AttributeIdentifierList = (DIC_US *)attributeIdentifierList;
 
502
 
 
503
        OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
 
504
        if (cond.good()) status = response.msg.NGetRSP.DimseStatus;
 
505
        if (status != 0) {
 
506
        LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
 
507
        std::ostringstream ostr;
 
508
        ostr << "Error sending create rq status: "<< status << " details: ";
 
509
        DIMSE_printNStatusString(ostr, status);
 
510
        throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
 
511
        }
 
512
        if (statusDetail) delete statusDetail;
 
513
        return cond;   
 
514
        */
 
515
        return false;
 
516
}
 
517
 
 
518
bool CustomAssociation::actionRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, int /*actionTypeID*/, const GIL::DICOM::DicomDataset& /*actionInformation*/, int& /*status*/,  GNC::GCS::Ptr<GIL::DICOM::DicomDataset>& /*attributeListOut*/)
 
519
        /*
 
520
        OFCondition CustomAssociation::actionRQ(
 
521
        const char *sopclassUID, 
 
522
        const char *sopinstanceUID, 
 
523
        Uint16 actionTypeID, 
 
524
        DcmDataset *actionInformation,
 
525
        Uint16& status, 
 
526
        DcmDataset* &actionReply)
 
527
        */
 
528
{
 
529
        /*
 
530
        if (assoc == NULL)
 
531
        {
 
532
        return DIMSE_ILLEGALASSOCIATION;
 
533
        }
 
534
        if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
 
535
        {
 
536
        return DIMSE_NULLKEY;
 
537
        }
 
538
 
 
539
        T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
 
540
        if (presCtx == 0)
 
541
        {
 
542
        return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
 
543
        }  
 
544
 
 
545
        T_DIMSE_Message request;
 
546
        T_DIMSE_Message response;
 
547
        DcmDataset *statusDetail = NULL;
 
548
 
 
549
        // construct N-ACTION-RQ
 
550
        request.CommandField = DIMSE_N_ACTION_RQ;
 
551
        request.msg.NActionRQ.MessageID = assoc->nextMsgID++;
 
552
        strcpy(request.msg.NActionRQ.RequestedSOPClassUID, sopclassUID);
 
553
        strcpy(request.msg.NActionRQ.RequestedSOPInstanceUID, sopinstanceUID);
 
554
        request.msg.NActionRQ.ActionTypeID = (DIC_US)actionTypeID;
 
555
        ////////TODO: EST� FALLANDO
 
556
        OFCondition cond = sendNRequest(presCtx, request, actionInformation, response, statusDetail, actionReply);
 
557
        if (cond.good()) status = response.msg.NActionRSP.DimseStatus;
 
558
        if (status != 0) {
 
559
        LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
 
560
        std::ostringstream ostr;
 
561
        ostr << "Error sending create rq status: "<< status << " details: ";
 
562
        DIMSE_printNStatusString(ostr, status);
 
563
        throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
 
564
        }
 
565
        if (statusDetail) delete statusDetail;
 
566
        return cond;   
 
567
        */
 
568
        return false;
692
569
}
693
570
 
694
571
bool CustomAssociation::deleteRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, int& /*status*/)
695
 
/*
696
 
OFCondition CustomAssociation::deleteRQ(
697
 
    const char *sopclassUID, 
698
 
    const char *sopinstanceUID, 
699
 
    Uint16& status)
 
572
        /*
 
573
        OFCondition CustomAssociation::deleteRQ(
 
574
        const char *sopclassUID, 
 
575
        const char *sopinstanceUID, 
 
576
        Uint16& status)
700
577
        */
701
578
{
702
579
        /*
703
 
  if (assoc == NULL)
704
 
  {
705
 
    return DIMSE_ILLEGALASSOCIATION;
706
 
  }
707
 
  if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
708
 
  {
709
 
    return DIMSE_NULLKEY;
710
 
  }
711
 
 
712
 
  T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
713
 
  if (presCtx == 0)
714
 
  {
715
 
    return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
716
 
  }  
717
 
 
718
 
  T_DIMSE_Message request;
719
 
  T_DIMSE_Message response;
720
 
  DcmDataset *statusDetail = NULL;
721
 
  DcmDataset *attributeListOut = NULL;
722
 
 
723
 
  // construct N-DELETE-RQ
724
 
  request.CommandField = DIMSE_N_DELETE_RQ;
725
 
  request.msg.NDeleteRQ.MessageID = assoc->nextMsgID++;
726
 
  strcpy(request.msg.NDeleteRQ.RequestedSOPClassUID, sopclassUID);
727
 
  strcpy(request.msg.NDeleteRQ.RequestedSOPInstanceUID, sopinstanceUID);
728
 
   
729
 
  OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
730
 
  if (cond.good()) status = response.msg.NDeleteRSP.DimseStatus;
731
 
  if (status != 0) {
732
 
         LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
733
 
         std::ostringstream ostr;
734
 
         ostr << "Error sending create rq status: "<< status << " details: ";
735
 
         DIMSE_printNStatusString(ostr, status);
736
 
         throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
737
 
  }
738
 
  if (statusDetail) delete statusDetail;
739
 
  if (attributeListOut) delete attributeListOut;  // should never happen
740
 
  return cond;   
741
 
  */
 
580
        if (assoc == NULL)
 
581
        {
 
582
        return DIMSE_ILLEGALASSOCIATION;
 
583
        }
 
584
        if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
 
585
        {
 
586
        return DIMSE_NULLKEY;
 
587
        }
 
588
 
 
589
        T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
 
590
        if (presCtx == 0)
 
591
        {
 
592
        return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
 
593
        }  
 
594
 
 
595
        T_DIMSE_Message request;
 
596
        T_DIMSE_Message response;
 
597
        DcmDataset *statusDetail = NULL;
 
598
        DcmDataset *attributeListOut = NULL;
 
599
 
 
600
        // construct N-DELETE-RQ
 
601
        request.CommandField = DIMSE_N_DELETE_RQ;
 
602
        request.msg.NDeleteRQ.MessageID = assoc->nextMsgID++;
 
603
        strcpy(request.msg.NDeleteRQ.RequestedSOPClassUID, sopclassUID);
 
604
        strcpy(request.msg.NDeleteRQ.RequestedSOPInstanceUID, sopinstanceUID);
 
605
 
 
606
        OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
 
607
        if (cond.good()) status = response.msg.NDeleteRSP.DimseStatus;
 
608
        if (status != 0) {
 
609
        LOG_ERROR(ambitolog, "Error sending create rq status: "<< status);
 
610
        std::ostringstream ostr;
 
611
        ostr << "Error sending create rq status: "<< status << " details: ";
 
612
        DIMSE_printNStatusString(ostr, status);
 
613
        throw GIL::DICOM::PACSException(ostr.str(), "GIL::CustomAssociation");
 
614
        }
 
615
        if (statusDetail) delete statusDetail;
 
616
        if (attributeListOut) delete attributeListOut;  // should never happen
 
617
        return cond;   
 
618
        */
742
619
        return false;
743
620
}
744
621
 
745
622
bool CustomAssociation::releaseAssociation() 
746
 
/*
747
 
OFCondition CustomAssociation::releaseAssociation()
748
 
*/
 
623
        /*
 
624
        OFCondition CustomAssociation::releaseAssociation()
 
625
        */
749
626
{
750
627
        /*
751
 
  OFCondition result = EC_Normal;
752
 
  if (assoc)
753
 
  {
754
 
    result = ASC_releaseAssociation(assoc);
755
 
         Drop();
756
 
         Destroy();
757
 
    assoc = NULL;
758
 
  }
759
 
  return result;
760
 
  */
 
628
        OFCondition result = EC_Normal;
 
629
        if (assoc)
 
630
        {
 
631
        result = ASC_releaseAssociation(assoc);
 
632
        Drop();
 
633
        Destroy();
 
634
        assoc = NULL;
 
635
        }
 
636
        return result;
 
637
        */
761
638
        return false;
762
639
}
763
640
 
764
641
bool CustomAssociation::abortAssociation()
765
 
/*
766
 
OFCondition CustomAssociation::abortAssociation()
767
 
*/
 
642
        /*
 
643
        OFCondition CustomAssociation::abortAssociation()
 
644
        */
768
645
{
769
 
/*      
770
 
  OFCondition result = EC_Normal;
771
 
  if (assoc)
772
 
  {
773
 
    result = ASC_abortAssociation(assoc);
774
 
         Drop();
775
 
         Destroy();
776
 
         assoc =  NULL;
777
 
  }
778
 
  return result;
779
 
  */
 
646
        /*      
 
647
        OFCondition result = EC_Normal;
 
648
        if (assoc)
 
649
        {
 
650
        result = ASC_abortAssociation(assoc);
 
651
        Drop();
 
652
        Destroy();
 
653
        assoc =  NULL;
 
654
        }
 
655
        return result;
 
656
        */
780
657
        return false;
781
658
}
782
659
 
783
660
T_ASC_PresentationContextID CustomAssociation::findAcceptedPC(const char *sopclassuid)
784
661
{
785
662
        /*
786
 
  if ((assoc==NULL)||(sopclassuid==NULL)) return 0;
 
663
        if ((assoc==NULL)||(sopclassuid==NULL)) return 0;
787
664
 
788
 
  // if the SOP class is one of the Basic Grayscale Print Management Meta SOP Classes,
789
 
  // look for a presentation context for Basic Grayscale Print.
790
 
  OFString sopclass(sopclassuid);
791
 
  if ((sopclass == UID_BasicFilmSessionSOPClass) ||
792
 
      (sopclass == UID_BasicFilmBoxSOPClass) ||
793
 
      (sopclass == UID_BasicGrayscaleImageBoxSOPClass) ||
794
 
      (sopclass == UID_PrinterSOPClass)) sopclassuid = UID_BasicGrayscalePrintManagementMetaSOPClass;
795
 
          */
796
 
        OFString sopclass(sopclassuid);
797
 
  return ASC_findAcceptedPresentationContextID(assoc, sopclassuid);
 
665
        // if the SOP class is one of the Basic Grayscale Print Management Meta SOP Classes,
 
666
        // look for a presentation context for Basic Grayscale Print.
 
667
        OFString sopclass(sopclassuid);
 
668
        if ((sopclass == UID_BasicFilmSessionSOPClass) ||
 
669
        (sopclass == UID_BasicFilmBoxSOPClass) ||
 
670
        (sopclass == UID_BasicGrayscaleImageBoxSOPClass) ||
 
671
        (sopclass == UID_PrinterSOPClass)) sopclassuid = UID_BasicGrayscalePrintManagementMetaSOPClass;
 
672
        */
 
673
        OFString sopclass(sopclassuid);
 
674
        return ASC_findAcceptedPresentationContextID(assoc, sopclassuid);
798
675
}
799
676
 
800
677
 
804
681
        OFCondition cond;
805
682
        typedef GIL::DICOM::DicomDataset TJerarquia;
806
683
        typedef GIL::DICOM::ListaTags TListaTags;
807
 
        
 
684
 
808
685
        for (TListaTags::const_iterator it = base.tags.begin(); it != base.tags.end(); ++it) {
809
 
                //DcmElement* e = GIL::DICOM::DICOMManager::CrearElementoConValor((*it).first.c_str());
810
 
                
811
 
                if (e != NULL) {
812
 
                        const std::string& val = (*it).second;
813
 
                        if (val.size() > 0) {
814
 
                                e->putString( (*it).second.c_str() );
815
 
                        }                                       
816
 
                        
817
 
                        cond = query->insert(e, true, false);
818
 
 
819
 
                        if (cond.bad()) {
820
 
                                LOG_ERROR("PACSCONTROLLER", "No se pudo insertar el elemento: (" << e->getTag().toString().c_str() << "): " << cond.text());
821
 
                        }
822
 
                }
823
 
 
824
 
                for (TJerarquia::DatasetList::const_iterator it2 = base.secuencias.begin(); it2 != base.secuencias.end(); it2++) {
825
 
                        const TJerarquia& seq = (*it2);
826
 
                        //DcmElement* es = GIL::DICOM::DICOMManager::CrearElementoConValor(seq.tagName.c_str());                        
827
 
 
828
 
                        for (TJerarquia::DatasetList::const_iterator it3 = seq.items.begin(); it3 != seq.items.end(); it3++) {
829
 
                                const TJerarquia& item = (*it3);
830
 
                                DcmItem* di = new DcmItem();
831
 
 
832
 
                                for (TListaTags::const_iterator it4 = item.tags.begin(); it4 != item.tags.end(); it4++) {
833
 
                                        //DcmElement* ei = GIL::DICOM::DICOMManager::CrearElementoConValor((*it4).first.c_str());
834
 
                                        if (ei != NULL) {
835
 
                                                const std::string& val = (*it4).second;
836
 
                                                if (val.size() > 0) {
837
 
                                                        ei->putString( (*it4).second.c_str() );
838
 
                                                }                                       
839
 
                                                cond = di->insert(ei, true, false);
840
 
 
841
 
                                                if (cond.bad()) {
842
 
                                                        LOG_ERROR("PACSCONTROLLER", "No se pudo insertar el elemento: (" << ei->getTag().toString().c_str() << "): " << cond.text());
843
 
                                                }
844
 
                                        }
845
 
 
846
 
                                }
847
 
 
848
 
                                query->insertSequenceItem(es->getTag(), di);
849
 
                        }                                       
850
 
                }
 
686
        //DcmElement* e = GIL::DICOM::DICOMManager::CrearElementoConValor((*it).first.c_str());
 
687
 
 
688
        if (e != NULL) {
 
689
        const std::string& val = (*it).second;
 
690
        if (val.size() > 0) {
 
691
        e->putString( (*it).second.c_str() );
 
692
        }                                       
 
693
 
 
694
        cond = query->insert(e, true, false);
 
695
 
 
696
        if (cond.bad()) {
 
697
        LOG_ERROR("PACSCONTROLLER", "No se pudo insertar el elemento: (" << e->getTag().toString().c_str() << "): " << cond.text());
 
698
        }
 
699
        }
 
700
 
 
701
        for (TJerarquia::DatasetList::const_iterator it2 = base.secuencias.begin(); it2 != base.secuencias.end(); it2++) {
 
702
        const TJerarquia& seq = (*it2);
 
703
        //DcmElement* es = GIL::DICOM::DICOMManager::CrearElementoConValor(seq.tagName.c_str());                        
 
704
 
 
705
        for (TJerarquia::DatasetList::const_iterator it3 = seq.items.begin(); it3 != seq.items.end(); it3++) {
 
706
        const TJerarquia& item = (*it3);
 
707
        DcmItem* di = new DcmItem();
 
708
 
 
709
        for (TListaTags::const_iterator it4 = item.tags.begin(); it4 != item.tags.end(); it4++) {
 
710
        //DcmElement* ei = GIL::DICOM::DICOMManager::CrearElementoConValor((*it4).first.c_str());
 
711
        if (ei != NULL) {
 
712
        const std::string& val = (*it4).second;
 
713
        if (val.size() > 0) {
 
714
        ei->putString( (*it4).second.c_str() );
 
715
        }                                       
 
716
        cond = di->insert(ei, true, false);
 
717
 
 
718
        if (cond.bad()) {
 
719
        LOG_ERROR("PACSCONTROLLER", "No se pudo insertar el elemento: (" << ei->getTag().toString().c_str() << "): " << cond.text());
 
720
        }
 
721
        }
 
722
 
 
723
        }
 
724
 
 
725
        query->insertSequenceItem(es->getTag(), di);
 
726
        }                                       
 
727
        }
851
728
        }
852
729
        */
853
730
}