138
139
CustomAssociation::~CustomAssociation() {
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)
144
CONDITION status = DIMSE_NORMAL;
146
//1. Open Association
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
151
if (!Net->Initiallized()) {
149
152
Net->InitializeNetwork(GetTimeout(), GetRole(), GetAcceptorPort());
159
SetNotificadorProgreso(m_pNotificadorProgreso);
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);
164
CONDITION c = ECC_Normal;
168
if (r.good() == true) {
172
DcmDataset* response;
174
DcmElement* e = NULL;
175
DcmSequenceOfItems* seq = NULL;
176
DcmItem* item = NULL;
178
e = newDicomElement(DCM_UnifiedProcedureStepState);
179
e->putString("SCHEDULED");
182
e = newDicomElement(DCM_ScheduledProcedureStepPriority);
183
e->putString("MEDIUM");
186
e = newDicomElement(DCM_WorklistLabel);
187
e->putString("worklist test");
190
e = newDicomElement(DCM_ProcedureStepLabel);
191
e->putString("test step");
194
e = newDicomElement(DCM_CommentsOnTheScheduledProcedureStep);
195
e->putString("comentarios");
198
e = newDicomElement(DCM_ScheduledProcedureStepStartDateTime);
199
e->putString("20120416114500");
202
e = newDicomElement(DCM_ExpectedCompletionDateTime);
203
e->putString("20120416144000");
207
e = newDicomElement(DCM_StudyInstanceUID);
208
if (parameters.getTag(GKDCM_StudyInstanceUID, strTmp)) {
209
e->putString(strTmp.c_str());
213
e = newDicomElement(DCM_PatientName);
214
if (parameters.getTag(GKDCM_PatientName, strTmp)) {
215
e->putString(strTmp.c_str());
219
e = newDicomElement(DCM_PatientID);
220
if (parameters.getTag(GKDCM_PatientID, strTmp)) {
221
e->putString(strTmp.c_str());
225
e = newDicomElement(DCM_AdmissionID);
226
if (parameters.getTag(GKDCM_AdmissionID, strTmp)) {
227
e->putString(strTmp.c_str());
231
e = newDicomElement(DCM_TransactionUID);
234
OFString upsSopInstanceUID;
235
c = createRQ(UID_UnifiedProcedureStepPushSOPClass, upsSopInstanceUID, &attrs, rstatus, response);
239
DcmDataset actionInformation;
240
e = newDicomElement(DCM_TransactionUID);
242
e->putString("1.2.40.0.13.1.1.10.231.162.70.20100921082909711.32774.1");
243
actionInformation.insert(e);
245
e = newDicomElement(DCM_UnifiedProcedureStepState);
246
e->putString("IN PROGRESS");
247
actionInformation.insert(e);
249
OFCondition resultStatus = actionRQ(UID_UnifiedProcedureStepPullSOPClass, upsSopInstanceUID.c_str(), 1, &actionInformation, rstatus, response);
162
CONDITION r = Association::Connect(Net, m_server->PDU);
260
165
LOG_ERROR(ambitolog, "Error al conectar:" << r.text());
263
168
throw GIL::DICOM::PACSException(r.text());
267
LOG_ERROR(ambitolog, "Error al enviar objeto: " << c.text());
270
throw GIL::DICOM::PACSException(c.text());
278
173
void CustomAssociation::OnAddPresentationContext(T_ASC_Parameters* params) {
279
OFCondition cond = EC_Normal;
281
const char* transferSyntaxes[3];
282
int transferSyntaxCount = 0;
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;
176
if (SOPClasses.size() > 0) {
177
GIL::DICOM::TransferSyntaxList tsList;
178
tsList.push_back(UID_LittleEndianImplicitTransferSyntax);
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);
190
LOG_WARN("C-GET", "Too many PresentationContexts setted");
193
LOG_WARN("C-GET", "NO PresentationContexts setted");
197
void CustomAssociation::dumpNMessage(T_DIMSE_Message &msg, DcmItem *dataset, OFBool outgoing)
201
DIMSE_dumpMessage(str, msg, DIMSE_OUTGOING, dataset);
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);
294
transferSyntaxes[2] = UID_LittleEndianImplicitTransferSyntax;
295
transferSyntaxCount = 3;
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);
301
void CustomAssociation::dumpNMessage(T_DIMSE_Message &msg, DcmItem *dataset, OFBool outgoing)
305
DIMSE_dumpMessage(str, msg, DIMSE_OUTGOING, dataset);
307
DIMSE_dumpMessage(str, msg, DIMSE_INCOMING, dataset);
309
LOG_DEBUG(ambitolog, str);
205
LOG_DEBUG(ambitolog, str);
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)
320
OFCondition cond = EC_Normal;
321
T_DIMSE_Command expectedResponse;
322
DIC_US expectedMessageID=0;
325
return DIMSE_ILLEGALASSOCIATION;
328
T_DIMSE_DataSetType datasetType = DIMSE_DATASET_NULL;
329
if (rqDataSet && (rqDataSet->card() > 0)) datasetType = DIMSE_DATASET_PRESENT;
331
switch(request.CommandField)
334
request.msg.NGetRQ.DataSetType = datasetType;
335
expectedResponse = DIMSE_N_GET_RSP;
336
expectedMessageID = request.msg.NGetRQ.MessageID;
339
request.msg.NSetRQ.DataSetType = datasetType;
340
expectedResponse = DIMSE_N_SET_RSP;
341
expectedMessageID = request.msg.NSetRQ.MessageID;
343
case DIMSE_N_ACTION_RQ:
344
request.msg.NActionRQ.DataSetType = datasetType;
345
expectedResponse = DIMSE_N_ACTION_RSP;
346
expectedMessageID = request.msg.NActionRQ.MessageID;
348
case DIMSE_N_CREATE_RQ:
349
request.msg.NCreateRQ.DataSetType = datasetType;
350
expectedResponse = DIMSE_N_CREATE_RSP;
351
expectedMessageID = request.msg.NCreateRQ.MessageID;
353
case DIMSE_N_DELETE_RQ:
354
request.msg.NDeleteRQ.DataSetType = datasetType;
355
expectedResponse = DIMSE_N_DELETE_RSP;
356
expectedMessageID = request.msg.NDeleteRQ.MessageID;
359
return DIMSE_BADCOMMANDTYPE;
363
dumpNMessage(request, rqDataSet, OFTrue);
364
cond = DIMSE_sendMessageUsingMemoryData(assoc, presId, &request, NULL, rqDataSet, NULL, NULL);
365
if (cond.bad()) return cond;
367
T_ASC_PresentationContextID thisPresId;
368
T_DIMSE_Message eventReportRsp;
369
DIC_US eventReportStatus;
374
cond = DIMSE_receiveCommand(assoc, blockMode, this->m_timeout, &thisPresId, &response, &statusDetail);
375
if (cond.bad()) return cond;
377
if (response.CommandField == DIMSE_N_EVENT_REPORT_RQ)
379
/* handle N-EVENT-REPORT-RQ */
381
if (response.msg.NEventReportRQ.DataSetType == DIMSE_DATASET_PRESENT)
383
cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
384
if (cond.bad()) return cond;
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;
392
if (statusDetail) delete statusDetail;
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;
408
/* No N-EVENT-REPORT-RQ. Check if this message is what we expected */
409
if (response.CommandField != expectedResponse)
412
sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
413
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
415
T_DIMSE_DataSetType responseDataset = DIMSE_DATASET_NULL;
416
DIC_US responseMessageID = 0;
417
/** change request to response */
418
switch(expectedResponse)
420
case DIMSE_N_GET_RSP:
421
responseDataset = response.msg.NGetRSP.DataSetType;
422
responseMessageID = response.msg.NGetRSP.MessageIDBeingRespondedTo;
424
case DIMSE_N_SET_RSP:
425
responseDataset = response.msg.NSetRSP.DataSetType;
426
responseMessageID = response.msg.NSetRSP.MessageIDBeingRespondedTo;
428
case DIMSE_N_ACTION_RSP:
429
responseDataset = response.msg.NActionRSP.DataSetType;
430
responseMessageID = response.msg.NActionRSP.MessageIDBeingRespondedTo;
432
case DIMSE_N_CREATE_RSP:
433
responseDataset = response.msg.NCreateRSP.DataSetType;
434
responseMessageID = response.msg.NCreateRSP.MessageIDBeingRespondedTo;
436
case DIMSE_N_DELETE_RSP:
437
responseDataset = response.msg.NDeleteRSP.DataSetType;
438
responseMessageID = response.msg.NDeleteRSP.MessageIDBeingRespondedTo;
443
sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
444
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
448
if (responseMessageID != expectedMessageID)
451
sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
452
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
455
if (responseDataset == DIMSE_DATASET_PRESENT)
457
cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
458
if (cond.bad()) return cond;
460
dumpNMessage(response, rspDataset, OFFalse);
462
} while (response.CommandField == DIMSE_N_EVENT_REPORT_RQ);
216
OFCondition cond = EC_Normal;
217
T_DIMSE_Command expectedResponse;
218
DIC_US expectedMessageID=0;
221
return DIMSE_ILLEGALASSOCIATION;
224
T_DIMSE_DataSetType datasetType = DIMSE_DATASET_NULL;
225
if (rqDataSet && (rqDataSet->card() > 0)) datasetType = DIMSE_DATASET_PRESENT;
227
switch(request.CommandField)
230
request.msg.NGetRQ.DataSetType = datasetType;
231
expectedResponse = DIMSE_N_GET_RSP;
232
expectedMessageID = request.msg.NGetRQ.MessageID;
235
request.msg.NSetRQ.DataSetType = datasetType;
236
expectedResponse = DIMSE_N_SET_RSP;
237
expectedMessageID = request.msg.NSetRQ.MessageID;
239
case DIMSE_N_ACTION_RQ:
240
request.msg.NActionRQ.DataSetType = datasetType;
241
expectedResponse = DIMSE_N_ACTION_RSP;
242
expectedMessageID = request.msg.NActionRQ.MessageID;
244
case DIMSE_N_CREATE_RQ:
245
request.msg.NCreateRQ.DataSetType = datasetType;
246
expectedResponse = DIMSE_N_CREATE_RSP;
247
expectedMessageID = request.msg.NCreateRQ.MessageID;
249
case DIMSE_N_DELETE_RQ:
250
request.msg.NDeleteRQ.DataSetType = datasetType;
251
expectedResponse = DIMSE_N_DELETE_RSP;
252
expectedMessageID = request.msg.NDeleteRQ.MessageID;
255
return DIMSE_BADCOMMANDTYPE;
259
dumpNMessage(request, rqDataSet, OFTrue);
260
cond = DIMSE_sendMessageUsingMemoryData(assoc, presId, &request, NULL, rqDataSet, NULL, NULL);
261
if (cond.bad()) return cond;
263
T_ASC_PresentationContextID thisPresId;
264
T_DIMSE_Message eventReportRsp;
265
DIC_US eventReportStatus;
270
cond = DIMSE_receiveCommand(assoc, blockMode, this->m_timeout, &thisPresId, &response, &statusDetail);
271
if (cond.bad()) return cond;
273
if (response.CommandField == DIMSE_N_EVENT_REPORT_RQ)
275
/* handle N-EVENT-REPORT-RQ */
277
if (response.msg.NEventReportRQ.DataSetType == DIMSE_DATASET_PRESENT)
279
cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
280
if (cond.bad()) return cond;
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;
288
if (statusDetail) delete statusDetail;
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;
304
/* No N-EVENT-REPORT-RQ. Check if this message is what we expected */
305
if (response.CommandField != expectedResponse)
308
sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
309
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
311
T_DIMSE_DataSetType responseDataset = DIMSE_DATASET_NULL;
312
DIC_US responseMessageID = 0;
313
/** change request to response */
314
switch(expectedResponse)
316
case DIMSE_N_GET_RSP:
317
responseDataset = response.msg.NGetRSP.DataSetType;
318
responseMessageID = response.msg.NGetRSP.MessageIDBeingRespondedTo;
320
case DIMSE_N_SET_RSP:
321
responseDataset = response.msg.NSetRSP.DataSetType;
322
responseMessageID = response.msg.NSetRSP.MessageIDBeingRespondedTo;
324
case DIMSE_N_ACTION_RSP:
325
responseDataset = response.msg.NActionRSP.DataSetType;
326
responseMessageID = response.msg.NActionRSP.MessageIDBeingRespondedTo;
328
case DIMSE_N_CREATE_RSP:
329
responseDataset = response.msg.NCreateRSP.DataSetType;
330
responseMessageID = response.msg.NCreateRSP.MessageIDBeingRespondedTo;
332
case DIMSE_N_DELETE_RSP:
333
responseDataset = response.msg.NDeleteRSP.DataSetType;
334
responseMessageID = response.msg.NDeleteRSP.MessageIDBeingRespondedTo;
339
sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
340
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
344
if (responseMessageID != expectedMessageID)
347
sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)response.CommandField);
348
return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
351
if (responseDataset == DIMSE_DATASET_PRESENT)
353
cond = DIMSE_receiveDataSetInMemory(assoc, blockMode, m_timeout, &thisPresId, &rspDataset, NULL, NULL);
354
if (cond.bad()) return cond;
356
dumpNMessage(response, rspDataset, OFFalse);
358
} while (response.CommandField == DIMSE_N_EVENT_REPORT_RQ);
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*/)
468
OFCondition CustomAssociation::createRQ(
469
const char *sopclassUID,
470
OFString& sopinstanceUID,
471
DcmDataset *attributeListIn,
473
DcmDataset* &attributeListOut)
479
return DIMSE_ILLEGALASSOCIATION;
481
if (sopclassUID==NULL)
483
return DIMSE_NULLKEY;
486
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
489
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
492
T_DIMSE_Message request;
493
T_DIMSE_Message response;
494
DcmDataset *statusDetail = NULL;
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)
502
strcpy(request.msg.NCreateRQ.AffectedSOPInstanceUID, sopinstanceUID.c_str());
503
request.msg.NCreateRQ.opts = O_NCREATE_AFFECTEDSOPINSTANCEUID;
505
request.msg.NCreateRQ.AffectedSOPInstanceUID[0] = 0;
506
request.msg.NCreateRQ.opts = 0;
509
OFCondition cond = sendNRequest(presCtx, request, attributeListIn, response, statusDetail, attributeListOut);
510
if (statusDetail) delete statusDetail;
513
status = response.msg.NCreateRSP.DimseStatus;
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");
521
// if response contains SOP Instance UID, copy it.
522
if (response.msg.NCreateRSP.opts & O_NCREATE_AFFECTEDSOPINSTANCEUID)
524
sopinstanceUID = response.msg.NCreateRSP.AffectedSOPInstanceUID;
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*/)
537
OFCondition CustomAssociation::setRQ(
538
const char *sopclassUID,
539
const char *sopinstanceUID,
540
DcmDataset *modificationList,
542
DcmDataset* &attributeListOut)
548
return DIMSE_ILLEGALASSOCIATION;
550
if ((sopclassUID==NULL)||(sopinstanceUID==NULL)||(modificationList==NULL))
552
return DIMSE_NULLKEY;
555
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
558
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
561
T_DIMSE_Message request;
562
T_DIMSE_Message response;
563
DcmDataset *statusDetail = NULL;
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);
571
OFCondition cond = sendNRequest(presCtx, request, modificationList, response, statusDetail, attributeListOut);
572
if (cond.good()) status = response.msg.NSetRSP.DimseStatus;
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");
580
if (statusDetail) delete statusDetail;
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*/)
588
OFCondition CustomAssociation::getRQ(
589
const char *sopclassUID,
590
const char *sopinstanceUID,
591
const Uint16 *attributeIdentifierList,
594
DcmDataset* &attributeListOut)
600
return DIMSE_ILLEGALASSOCIATION;
602
if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
604
return DIMSE_NULLKEY;
607
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
610
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
613
T_DIMSE_Message request;
614
T_DIMSE_Message response;
615
DcmDataset *statusDetail = NULL;
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;
626
OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
627
if (cond.good()) status = response.msg.NGetRSP.DimseStatus;
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");
635
if (statusDetail) delete statusDetail;
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*/)
643
OFCondition CustomAssociation::actionRQ(
644
const char *sopclassUID,
645
const char *sopinstanceUID,
647
DcmDataset *actionInformation,
649
DcmDataset* &actionReply)
655
return DIMSE_ILLEGALASSOCIATION;
657
if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
659
return DIMSE_NULLKEY;
662
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
665
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
668
T_DIMSE_Message request;
669
T_DIMSE_Message response;
670
DcmDataset *statusDetail = NULL;
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;
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)
366
LOG_ERROR(ambitolog, DIMSE_ILLEGALASSOCIATION.text());
371
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID.c_str());
374
LOG_ERROR(ambitolog, DIMSE_NOVALIDPRESENTATIONCONTEXTID.text());
378
T_DIMSE_Message request;
379
T_DIMSE_Message response;
380
DcmDataset *statusDetail = NULL;
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;
391
GIL::DICOM::PACSController::Instance()->FillInQuery(attributeListIn, &inAttr, m_server);
393
OFCondition cond = sendNRequest(presCtx, request, &inAttr, response, statusDetail, outAttr);
400
status = response.msg.NCreateRSP.DimseStatus;
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");
408
// if response contains SOP Instance UID, copy it.
409
if (response.msg.NCreateRSP.opts & O_NCREATE_AFFECTEDSOPINSTANCEUID)
411
affectedSopinstanceUID = response.msg.NCreateRSP.AffectedSOPInstanceUID;
420
bool CustomAssociation::setRQ( const std::string& sopclassUID, const std::string& sopinstanceUID, const GIL::DICOM::DicomDataset& modificationList, int& status)
424
LOG_ERROR(ambitolog, DIMSE_ILLEGALASSOCIATION.text());
429
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID.c_str());
432
LOG_ERROR(ambitolog, DIMSE_NOVALIDPRESENTATIONCONTEXTID.text());
436
T_DIMSE_Message request;
437
T_DIMSE_Message response;
438
DcmDataset *statusDetail = NULL;
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());
448
GIL::DICOM::PACSController::Instance()->FillInQuery(modificationList, &inAttr, m_server);
450
OFCondition cond = sendNRequest(presCtx, request, &inAttr, response, statusDetail, outAttr);
451
if (cond.good()) status = response.msg.NSetRSP.DimseStatus;
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");
688
if (statusDetail) delete statusDetail;
459
if (statusDetail) delete statusDetail;
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*/)
465
OFCondition CustomAssociation::getRQ(
466
const char *sopclassUID,
467
const char *sopinstanceUID,
468
const Uint16 *attributeIdentifierList,
471
DcmDataset* &attributeListOut)
477
return DIMSE_ILLEGALASSOCIATION;
479
if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
481
return DIMSE_NULLKEY;
484
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
487
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
490
T_DIMSE_Message request;
491
T_DIMSE_Message response;
492
DcmDataset *statusDetail = NULL;
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;
503
OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
504
if (cond.good()) status = response.msg.NGetRSP.DimseStatus;
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");
512
if (statusDetail) delete statusDetail;
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*/)
520
OFCondition CustomAssociation::actionRQ(
521
const char *sopclassUID,
522
const char *sopinstanceUID,
524
DcmDataset *actionInformation,
526
DcmDataset* &actionReply)
532
return DIMSE_ILLEGALASSOCIATION;
534
if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
536
return DIMSE_NULLKEY;
539
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
542
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
545
T_DIMSE_Message request;
546
T_DIMSE_Message response;
547
DcmDataset *statusDetail = NULL;
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;
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");
565
if (statusDetail) delete statusDetail;
694
571
bool CustomAssociation::deleteRQ( const std::string& /*sopclassUID*/, const std::string& /*sopinstanceUID*/, int& /*status*/)
696
OFCondition CustomAssociation::deleteRQ(
697
const char *sopclassUID,
698
const char *sopinstanceUID,
573
OFCondition CustomAssociation::deleteRQ(
574
const char *sopclassUID,
575
const char *sopinstanceUID,
705
return DIMSE_ILLEGALASSOCIATION;
707
if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
709
return DIMSE_NULLKEY;
712
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
715
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
718
T_DIMSE_Message request;
719
T_DIMSE_Message response;
720
DcmDataset *statusDetail = NULL;
721
DcmDataset *attributeListOut = NULL;
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);
729
OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
730
if (cond.good()) status = response.msg.NDeleteRSP.DimseStatus;
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");
738
if (statusDetail) delete statusDetail;
739
if (attributeListOut) delete attributeListOut; // should never happen
582
return DIMSE_ILLEGALASSOCIATION;
584
if ((sopclassUID==NULL)||(sopinstanceUID==NULL))
586
return DIMSE_NULLKEY;
589
T_ASC_PresentationContextID presCtx = findAcceptedPC(sopclassUID);
592
return DIMSE_NOVALIDPRESENTATIONCONTEXTID;
595
T_DIMSE_Message request;
596
T_DIMSE_Message response;
597
DcmDataset *statusDetail = NULL;
598
DcmDataset *attributeListOut = NULL;
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);
606
OFCondition cond = sendNRequest(presCtx, request, NULL, response, statusDetail, attributeListOut);
607
if (cond.good()) status = response.msg.NDeleteRSP.DimseStatus;
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");
615
if (statusDetail) delete statusDetail;
616
if (attributeListOut) delete attributeListOut; // should never happen
745
622
bool CustomAssociation::releaseAssociation()
747
OFCondition CustomAssociation::releaseAssociation()
624
OFCondition CustomAssociation::releaseAssociation()
751
OFCondition result = EC_Normal;
754
result = ASC_releaseAssociation(assoc);
628
OFCondition result = EC_Normal;
631
result = ASC_releaseAssociation(assoc);
764
641
bool CustomAssociation::abortAssociation()
766
OFCondition CustomAssociation::abortAssociation()
643
OFCondition CustomAssociation::abortAssociation()
770
OFCondition result = EC_Normal;
773
result = ASC_abortAssociation(assoc);
647
OFCondition result = EC_Normal;
650
result = ASC_abortAssociation(assoc);
783
660
T_ASC_PresentationContextID CustomAssociation::findAcceptedPC(const char *sopclassuid)
786
if ((assoc==NULL)||(sopclassuid==NULL)) return 0;
663
if ((assoc==NULL)||(sopclassuid==NULL)) return 0;
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;
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;
673
OFString sopclass(sopclassuid);
674
return ASC_findAcceptedPresentationContextID(assoc, sopclassuid);