comparison OrthancServer/Internals/CommandDispatcher.cpp @ 503:273e7ad98ea9

promiscuous mode
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 13 Aug 2013 08:49:07 +0200
parents 4d5f0857ec9c
children 4aa6f0d79947
comparison
equal deleted inserted replaced
501:7395fbb17c07 503:273e7ad98ea9
39 39
40 #include <dcmtk/dcmnet/dcasccfg.h> /* for class DcmAssociationConfiguration */ 40 #include <dcmtk/dcmnet/dcasccfg.h> /* for class DcmAssociationConfiguration */
41 #include <boost/lexical_cast.hpp> 41 #include <boost/lexical_cast.hpp>
42 #include <glog/logging.h> 42 #include <glog/logging.h>
43 43
44 #define ORTHANC_PROMISCUOUS 1
45
44 static OFBool opt_rejectWithoutImplementationUID = OFFalse; 46 static OFBool opt_rejectWithoutImplementationUID = OFFalse;
47
48
49
50 #if ORTHANC_PROMISCUOUS == 1
51 static
52 DUL_PRESENTATIONCONTEXT *
53 findPresentationContextID(LST_HEAD * head,
54 T_ASC_PresentationContextID presentationContextID)
55 {
56 DUL_PRESENTATIONCONTEXT *pc;
57 LST_HEAD **l;
58 OFBool found = OFFalse;
59
60 if (head == NULL)
61 return NULL;
62
63 l = &head;
64 if (*l == NULL)
65 return NULL;
66
67 pc = OFstatic_cast(DUL_PRESENTATIONCONTEXT *, LST_Head(l));
68 (void)LST_Position(l, OFstatic_cast(LST_NODE *, pc));
69
70 while (pc && !found) {
71 if (pc->presentationContextID == presentationContextID) {
72 found = OFTrue;
73 } else {
74 pc = OFstatic_cast(DUL_PRESENTATIONCONTEXT *, LST_Next(l));
75 }
76 }
77 return pc;
78 }
79
80
81 /** accept all presenstation contexts for unknown SOP classes,
82 * i.e. UIDs appearing in the list of abstract syntaxes
83 * where no corresponding name is defined in the UID dictionary.
84 * @param params pointer to association parameters structure
85 * @param transferSyntax transfer syntax to accept
86 * @param acceptedRole SCU/SCP role to accept
87 */
88 static OFCondition acceptUnknownContextsWithTransferSyntax(
89 T_ASC_Parameters * params,
90 const char* transferSyntax,
91 T_ASC_SC_ROLE acceptedRole)
92 {
93 OFCondition cond = EC_Normal;
94 int n, i, k;
95 DUL_PRESENTATIONCONTEXT *dpc;
96 T_ASC_PresentationContext pc;
97 OFBool accepted = OFFalse;
98 OFBool abstractOK = OFFalse;
99
100 n = ASC_countPresentationContexts(params);
101 for (i = 0; i < n; i++)
102 {
103 cond = ASC_getPresentationContext(params, i, &pc);
104 if (cond.bad()) return cond;
105 abstractOK = OFFalse;
106 accepted = OFFalse;
107
108 if (dcmFindNameOfUID(pc.abstractSyntax) == NULL)
109 {
110 abstractOK = OFTrue;
111
112 /* check the transfer syntax */
113 for (k = 0; (k < OFstatic_cast(int, pc.transferSyntaxCount)) && !accepted; k++)
114 {
115 if (strcmp(pc.proposedTransferSyntaxes[k], transferSyntax) == 0)
116 {
117 accepted = OFTrue;
118 }
119 }
120 }
121
122 if (accepted)
123 {
124 cond = ASC_acceptPresentationContext(
125 params, pc.presentationContextID,
126 transferSyntax, acceptedRole);
127 if (cond.bad()) return cond;
128 } else {
129 T_ASC_P_ResultReason reason;
130
131 /* do not refuse if already accepted */
132 dpc = findPresentationContextID(params->DULparams.acceptedPresentationContext,
133 pc.presentationContextID);
134 if ((dpc == NULL) || ((dpc != NULL) && (dpc->result != ASC_P_ACCEPTANCE)))
135 {
136
137 if (abstractOK) {
138 reason = ASC_P_TRANSFERSYNTAXESNOTSUPPORTED;
139 } else {
140 reason = ASC_P_ABSTRACTSYNTAXNOTSUPPORTED;
141 }
142 /*
143 * If previously this presentation context was refused
144 * because of bad transfer syntax let it stay that way.
145 */
146 if ((dpc != NULL) && (dpc->result == ASC_P_TRANSFERSYNTAXESNOTSUPPORTED))
147 reason = ASC_P_TRANSFERSYNTAXESNOTSUPPORTED;
148
149 cond = ASC_refusePresentationContext(params, pc.presentationContextID, reason);
150 if (cond.bad()) return cond;
151 }
152 }
153 }
154 return EC_Normal;
155 }
156
157
158 /** accept all presenstation contexts for unknown SOP classes,
159 * i.e. UIDs appearing in the list of abstract syntaxes
160 * where no corresponding name is defined in the UID dictionary.
161 * This method is passed a list of "preferred" transfer syntaxes.
162 * @param params pointer to association parameters structure
163 * @param transferSyntax transfer syntax to accept
164 * @param acceptedRole SCU/SCP role to accept
165 */
166 static OFCondition acceptUnknownContextsWithPreferredTransferSyntaxes(
167 T_ASC_Parameters * params,
168 const char* transferSyntaxes[], int transferSyntaxCount,
169 T_ASC_SC_ROLE acceptedRole = ASC_SC_ROLE_DEFAULT)
170 {
171 OFCondition cond = EC_Normal;
172 /*
173 ** Accept in the order "least wanted" to "most wanted" transfer
174 ** syntax. Accepting a transfer syntax will override previously
175 ** accepted transfer syntaxes.
176 */
177 for (int i = transferSyntaxCount - 1; i >= 0; i--)
178 {
179 cond = acceptUnknownContextsWithTransferSyntax(params, transferSyntaxes[i], acceptedRole);
180 if (cond.bad()) return cond;
181 }
182 return cond;
183 }
184 #endif
45 185
46 186
47 namespace Orthanc 187 namespace Orthanc
48 { 188 {
49 namespace Internals 189 namespace Internals
147 { 287 {
148 LOG(INFO) << cond.text(); 288 LOG(INFO) << cond.text();
149 AssociationCleanup(assoc); 289 AssociationCleanup(assoc);
150 return NULL; 290 return NULL;
151 } 291 }
292
293 #if ORTHANC_PROMISCUOUS == 1
294 /* accept everything not known not to be a storage SOP class */
295 cond = acceptUnknownContextsWithPreferredTransferSyntaxes(
296 assoc->params, transferSyntaxes, numTransferSyntaxes);
297 if (cond.bad())
298 {
299 LOG(INFO) << cond.text();
300 AssociationCleanup(assoc);
301 return NULL;
302 }
303 #endif
152 304
153 /* set our app title */ 305 /* set our app title */
154 ASC_setAPTitles(assoc->params, NULL, NULL, server.GetApplicationEntityTitle().c_str()); 306 ASC_setAPTitles(assoc->params, NULL, NULL, server.GetApplicationEntityTitle().c_str());
155 307
156 /* acknowledge or reject this association */ 308 /* acknowledge or reject this association */