196 lines
5.3 KiB
C++
196 lines
5.3 KiB
C++
#include "dcm_verify.h"
|
|
|
|
/* DICOM standard transfer syntaxes */
|
|
static const char* transferSyntaxes[] = {
|
|
UID_LittleEndianImplicitTransferSyntax, /* default xfer syntax first */
|
|
UID_LittleEndianExplicitTransferSyntax,
|
|
UID_BigEndianExplicitTransferSyntax,
|
|
UID_JPEGProcess1TransferSyntax,
|
|
UID_JPEGProcess2_4TransferSyntax,
|
|
UID_JPEGProcess3_5TransferSyntax,
|
|
UID_JPEGProcess6_8TransferSyntax,
|
|
UID_JPEGProcess7_9TransferSyntax,
|
|
UID_JPEGProcess10_12TransferSyntax,
|
|
UID_JPEGProcess11_13TransferSyntax,
|
|
UID_JPEGProcess14TransferSyntax,
|
|
UID_JPEGProcess15TransferSyntax,
|
|
UID_JPEGProcess16_18TransferSyntax,
|
|
UID_JPEGProcess17_19TransferSyntax,
|
|
UID_JPEGProcess20_22TransferSyntax,
|
|
UID_JPEGProcess21_23TransferSyntax,
|
|
UID_JPEGProcess24_26TransferSyntax,
|
|
UID_JPEGProcess25_27TransferSyntax,
|
|
UID_JPEGProcess28TransferSyntax,
|
|
UID_JPEGProcess29TransferSyntax,
|
|
UID_JPEGProcess14SV1TransferSyntax,
|
|
UID_RLELosslessTransferSyntax,
|
|
UID_DeflatedExplicitVRLittleEndianTransferSyntax,
|
|
UID_JPEGLSLosslessTransferSyntax,
|
|
UID_JPEGLSLossyTransferSyntax,
|
|
UID_JPEG2000LosslessOnlyTransferSyntax,
|
|
UID_JPEG2000TransferSyntax,
|
|
UID_JPEG2000Part2MulticomponentImageCompressionLosslessOnlyTransferSyntax,
|
|
UID_JPEG2000Part2MulticomponentImageCompressionTransferSyntax,
|
|
UID_MPEG2MainProfileAtMainLevelTransferSyntax,
|
|
UID_MPEG2MainProfileAtHighLevelTransferSyntax,
|
|
UID_MPEG4HighProfileLevel4_1TransferSyntax,
|
|
UID_MPEG4BDcompatibleHighProfileLevel4_1TransferSyntax,
|
|
UID_MPEG4HighProfileLevel4_2_For2DVideoTransferSyntax,
|
|
UID_MPEG4HighProfileLevel4_2_For3DVideoTransferSyntax,
|
|
UID_MPEG4StereoHighProfileLevel4_2TransferSyntax,
|
|
UID_HEVCMainProfileLevel5_1TransferSyntax,
|
|
UID_HEVCMain10ProfileLevel5_1TransferSyntax
|
|
};
|
|
|
|
dcm_cecho::dcm_cecho(const char *peerIp, unsigned long peerPort, const char *peerTitle, const char *ourTitle)
|
|
: maxReceivedPDULength(ASC_DEFAULTMAXPDU)
|
|
, repeatCount(1)
|
|
, abortAssociation(false)
|
|
, numXferSyntaxes(1)
|
|
, numPresentationCtx(1)
|
|
, aces_timeout(30)
|
|
, socket_tiemout(60)
|
|
, blockMode(DIMSE_BLOCKING)
|
|
, dimse_timeout(0)
|
|
|
|
{
|
|
maxXferSyntaxes = static_cast<unsigned long>(DIM_OF(transferSyntaxes));
|
|
peerIp_ = peerIp;
|
|
peerPort_ = peerPort;
|
|
peerTitle_ = peerTitle;
|
|
ourTitle_ = ourTitle;
|
|
}
|
|
|
|
dcm_cecho::~dcm_cecho()
|
|
{
|
|
}
|
|
|
|
void dcm_cecho::set_asce_timeout(int timeout)
|
|
{
|
|
aces_timeout = timeout;
|
|
}
|
|
|
|
void dcm_cecho::set_dimse_timeout(int timeout)
|
|
{
|
|
dimse_timeout = timeout;
|
|
}
|
|
|
|
void dcm_cecho::set_max_received_pdu_length(unsigned long length)
|
|
{
|
|
maxReceivedPDULength = length;
|
|
}
|
|
|
|
int dcm_cecho::docecho()
|
|
{
|
|
T_ASC_Network *cecho_net;
|
|
T_ASC_Parameters *cecho_params;
|
|
DIC_NODENAME cecho_peerHost;
|
|
T_ASC_Association *cecho_assoc;
|
|
|
|
OFStandard::initializeNetwork();
|
|
if (!dcmDataDict.isDictionaryLoaded())
|
|
return e_no_dictionary_loaded;
|
|
|
|
OFCondition cond = ASC_initializeNetwork(NET_REQUESTOR, 0, aces_timeout, &cecho_net);
|
|
if (cond.bad())
|
|
return cond.code(); // global error code should be a super set of condition error code
|
|
|
|
cond = ASC_createAssociationParameters(&cecho_params, maxReceivedPDULength);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
|
|
ASC_setAPTitles(cecho_params, ourTitle_, peerTitle_, NULL);
|
|
sprintf(cecho_peerHost, "%s:%d", peerIp_, static_cast<int>(peerPort_));
|
|
ASC_setPresentationAddresses(cecho_params, OFStandard::getHostName().c_str(), cecho_peerHost);
|
|
|
|
int presentationContextID = 1;
|
|
for (unsigned long ii = 0; ii < numPresentationCtx; ii++)
|
|
{
|
|
cond = ASC_addPresentationContext(cecho_params, presentationContextID, UID_VerificationSOPClass, transferSyntaxes, static_cast<int>(numXferSyntaxes));
|
|
presentationContextID += 2;
|
|
if (cond.bad())
|
|
return cond.code();
|
|
}
|
|
|
|
cond = ASC_requestAssociation(cecho_net, cecho_params, &cecho_assoc);
|
|
if (cond.bad())
|
|
{
|
|
if (cond == DUL_ASSOCIATIONREJECTED)
|
|
return e_association_rejected;
|
|
else
|
|
return cond.code();
|
|
}
|
|
|
|
if (ASC_countAcceptedPresentationContexts(cecho_params) == 0)
|
|
return e_no_acceptable_presentation_context;
|
|
|
|
cond = cecho(cecho_assoc, repeatCount, blockMode, dimse_timeout);
|
|
if (cond == EC_Normal)
|
|
{
|
|
if (abortAssociation)
|
|
{
|
|
cond = ASC_abortAssociation(cecho_assoc);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
}
|
|
else
|
|
{
|
|
cond = ASC_releaseAssociation(cecho_assoc);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
}
|
|
}
|
|
else if (cond == DUL_PEERREQUESTEDRELEASE)
|
|
{
|
|
cond = ASC_abortAssociation(cecho_assoc);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
}
|
|
else if (cond == DUL_PEERABORTEDASSOCIATION)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
cond = ASC_abortAssociation(cecho_assoc);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
}
|
|
|
|
cond = ASC_destroyAssociation(&cecho_assoc);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
|
|
cond = ASC_dropNetwork(&cecho_net);
|
|
if (cond.bad())
|
|
return cond.code();
|
|
|
|
OFStandard::shutdownNetwork();
|
|
return e_ok;
|
|
}
|
|
|
|
OFCondition dcm_cecho::echoSCU(T_ASC_Association * assoc, T_DIMSE_BlockingMode block_mode, int dimse_timeout)
|
|
{
|
|
DIC_US msgId = assoc->nextMsgID++;
|
|
DIC_US status;
|
|
DcmDataset *statusDetail = NULL;
|
|
|
|
// log >> "Sending Echo Request
|
|
OFCondition cond = DIMSE_echoUser(assoc, msgId, block_mode, dimse_timeout, &status, &statusDetail);
|
|
if (statusDetail != NULL)
|
|
delete statusDetail;
|
|
|
|
return cond;
|
|
}
|
|
|
|
OFCondition dcm_cecho::cecho(T_ASC_Association * assoc, unsigned long num_repeat, T_DIMSE_BlockingMode block_mode, int dimse_tiemout)
|
|
{
|
|
OFCondition cond = EC_Normal;
|
|
unsigned long n = num_repeat;
|
|
|
|
while (cond.good() && n--)
|
|
cond = echoSCU(assoc, block_mode, dimse_tiemout);
|
|
|
|
return cond;
|
|
}
|
|
|