void Association ::reject(Result result, ResultSource result_source, Diagnostic diagnostic) { T_ASC_RejectParameters reject_parameters; reject_parameters.result = T_ASC_RejectParametersResult(result); reject_parameters.source = T_ASC_RejectParametersSource(result_source); reject_parameters.reason = T_ASC_RejectParametersReason(diagnostic); OFCondition const condition = ASC_rejectAssociation( this->_association, &reject_parameters); if(condition.bad()) { throw Exception(condition); } }
CommandDispatcher* AcceptAssociation(const DicomServer& server, T_ASC_Network *net) { DcmAssociationConfiguration asccfg; char buf[BUFSIZ]; T_ASC_Association *assoc; OFCondition cond; OFString sprofile; OFString temp_str; std::vector<const char*> knownAbstractSyntaxes; // For C-STORE if (server.HasStoreRequestHandlerFactory()) { knownAbstractSyntaxes.push_back(UID_VerificationSOPClass); } // For C-FIND if (server.HasFindRequestHandlerFactory()) { knownAbstractSyntaxes.push_back(UID_FINDPatientRootQueryRetrieveInformationModel); knownAbstractSyntaxes.push_back(UID_FINDStudyRootQueryRetrieveInformationModel); } // For C-MOVE if (server.HasMoveRequestHandlerFactory()) { knownAbstractSyntaxes.push_back(UID_MOVEStudyRootQueryRetrieveInformationModel); } const char* transferSyntaxes[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int numTransferSyntaxes = 0; cond = ASC_receiveAssociation(net, &assoc, /*opt_maxPDU*/ ASC_DEFAULTMAXPDU, NULL, NULL, /*opt_secureConnection*/ OFFalse, DUL_NOBLOCK, 1); if (cond == DUL_NOASSOCIATIONREQUEST) { // Timeout AssociationCleanup(assoc); return NULL; } // if some kind of error occured, take care of it if (cond.bad()) { LOG(ERROR) << "Receiving Association failed: " << cond.text(); // no matter what kind of error occurred, we need to do a cleanup AssociationCleanup(assoc); return NULL; } LOG(INFO) << "Association Received"; transferSyntaxes[0] = UID_LittleEndianExplicitTransferSyntax; transferSyntaxes[1] = UID_BigEndianExplicitTransferSyntax; transferSyntaxes[2] = UID_LittleEndianImplicitTransferSyntax; numTransferSyntaxes = 3; /* accept the Verification SOP Class if presented */ cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, &knownAbstractSyntaxes[0], knownAbstractSyntaxes.size(), transferSyntaxes, numTransferSyntaxes); if (cond.bad()) { LOG(INFO) << cond.text(); AssociationCleanup(assoc); return NULL; } /* the array of Storage SOP Class UIDs comes from dcuid.h */ cond = ASC_acceptContextsWithPreferredTransferSyntaxes( assoc->params, dcmAllStorageSOPClassUIDs, numberOfAllDcmStorageSOPClassUIDs, transferSyntaxes, numTransferSyntaxes); if (cond.bad()) { LOG(INFO) << cond.text(); AssociationCleanup(assoc); return NULL; } /* set our app title */ ASC_setAPTitles(assoc->params, NULL, NULL, server.GetApplicationEntityTitle().c_str()); /* acknowledge or reject this association */ cond = ASC_getApplicationContextName(assoc->params, buf); if ((cond.bad()) || strcmp(buf, UID_StandardApplicationContext) != 0) { /* reject: the application context name is not supported */ T_ASC_RejectParameters rej = { ASC_RESULT_REJECTEDPERMANENT, ASC_SOURCE_SERVICEUSER, ASC_REASON_SU_APPCONTEXTNAMENOTSUPPORTED }; LOG(INFO) << "Association Rejected: Bad Application Context Name: " << buf; cond = ASC_rejectAssociation(assoc, &rej); if (cond.bad()) { LOG(INFO) << cond.text(); } AssociationCleanup(assoc); return NULL; } /* check the AETs */ { DIC_AE callingTitle_C; DIC_AE calledTitle_C; DIC_AE callingIP_C; DIC_AE calledIP_C; if (ASC_getAPTitles(assoc->params, callingTitle_C, calledTitle_C, NULL).bad() || ASC_getPresentationAddresses(assoc->params, callingIP_C, calledIP_C).bad()) { T_ASC_RejectParameters rej = { ASC_RESULT_REJECTEDPERMANENT, ASC_SOURCE_SERVICEUSER, ASC_REASON_SU_NOREASON }; ASC_rejectAssociation(assoc, &rej); AssociationCleanup(assoc); return NULL; } std::string callingIP(/*OFSTRING_GUARD*/(callingIP_C)); std::string callingTitle(/*OFSTRING_GUARD*/(callingTitle_C)); std::string calledTitle(/*OFSTRING_GUARD*/(calledTitle_C)); Toolbox::ToUpperCase(callingIP); Toolbox::ToUpperCase(callingTitle); Toolbox::ToUpperCase(calledTitle); if (server.HasCalledApplicationEntityTitleCheck() && calledTitle != server.GetApplicationEntityTitle()) { T_ASC_RejectParameters rej = { ASC_RESULT_REJECTEDPERMANENT, ASC_SOURCE_SERVICEUSER, ASC_REASON_SU_CALLEDAETITLENOTRECOGNIZED }; ASC_rejectAssociation(assoc, &rej); AssociationCleanup(assoc); return NULL; } if (server.HasApplicationEntityFilter() && !server.GetApplicationEntityFilter().IsAllowed(callingIP, callingTitle)) { T_ASC_RejectParameters rej = { ASC_RESULT_REJECTEDPERMANENT, ASC_SOURCE_SERVICEUSER, ASC_REASON_SU_CALLINGAETITLENOTRECOGNIZED }; ASC_rejectAssociation(assoc, &rej); AssociationCleanup(assoc); return NULL; } } if (opt_rejectWithoutImplementationUID && strlen(assoc->params->theirImplementationClassUID) == 0) { /* reject: the no implementation Class UID provided */ T_ASC_RejectParameters rej = { ASC_RESULT_REJECTEDPERMANENT, ASC_SOURCE_SERVICEUSER, ASC_REASON_SU_NOREASON }; LOG(INFO) << "Association Rejected: No Implementation Class UID provided"; cond = ASC_rejectAssociation(assoc, &rej); if (cond.bad()) { LOG(INFO) << cond.text(); } AssociationCleanup(assoc); return NULL; } { cond = ASC_acknowledgeAssociation(assoc); if (cond.bad()) { LOG(ERROR) << cond.text(); AssociationCleanup(assoc); return NULL; } LOG(INFO) << "Association Acknowledged (Max Send PDV: " << assoc->sendPDVLength << ")"; if (ASC_countAcceptedPresentationContexts(assoc->params) == 0) LOG(INFO) << " (but no valid presentation contexts)"; } return new CommandDispatcher(server, assoc); }