|
|
1.1 root 1: /* rosapapdu.c - ROPM: interpret APDU */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapapdu.c,v 7.1 90/07/01 21:05:58 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/rosap/RCS/rosapapdu.c,v 7.1 90/07/01 21:05:58 mrose Exp $
9: *
10: * Based on an TCP-based implementation by George Michaelson of University
11: * College London.
12: *
13: *
14: * $Log: rosapapdu.c,v $
15: * Revision 7.1 90/07/01 21:05:58 mrose
16: * pepsy
17: *
18: * Revision 6.0 89/03/18 23:42:22 mrose
19: * Release 5.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /* LINTLIBRARY */
35:
36: #include <stdio.h>
37: #include <signal.h>
38: #include "ROS-types.h"
39: #include "ropkt.h"
40: #ifdef DEBUG
41: #include "tailor.h"
42: #endif
43:
44: static int prob2num ();
45:
46: /* */
47:
48: int acb2osdu (acb, invokeID, pe, roi)
49: register struct assocblk *acb;
50: int *invokeID;
51: register PE pe;
52: register struct RoSAPindication *roi;
53: {
54: struct type_ROS_ROSEapdus *papdu;
55: struct type_ROS_OPDU *popdu;
56: int rosap_type;
57: int result;
58:
59: rosap_type = APDU_UNKNOWN;
60: if (((acb -> acb_flags & ACB_ACS)
61: ? decode_ROS_ROSEapdus (pe, 1, NULLIP, NULLVP, &papdu)
62: : decode_ROS_OPDU (pe, 1, NULLIP, NULLVP, &popdu))
63: == NOTOK) {
64: (void) rosapreject (acb, roi, rosap_type != APDU_UNKNOWN
65: ? ROS_GP_MISTYPED : ROS_GP_UNRECOG, NULLCP, "%s",
66: PY_pepy);
67: pe_free (pe);
68: return NOTOK;
69: }
70:
71: #ifdef DEBUG
72: if (rosap_log -> ll_events & LLOG_PDUS)
73: if (acb -> acb_flags & ACB_ACS)
74: pvpdu (rosap_log, print_ROS_ROSEapdus_P, pe, "ROSEapdus", 1);
75: else
76: pvpdu (rosap_log, print_ROS_OPDU_P, pe, "OPDU", 1);
77: #endif
78:
79: /* p = pe_expunge (pe, rosap_data); */
80:
81: if ((acb -> acb_flags & ACB_ACS)) {
82: result = apdu_proc (acb -> acb_fd, papdu, roi, acb, invokeID);
83: if (papdu)
84: free_ROS_ROSEapdus (papdu);
85: }
86: else {
87: result = opdu_proc (acb -> acb_fd, popdu, roi, acb, invokeID);
88: if (popdu)
89: free_ROS_OPDU (popdu);
90: }
91:
92: return (result);
93: }
94:
95: /* */
96:
97: /*
98: * Process an APDU. This seperates out all the differences between
99: * the two cases. Copy all the fields of the structure into the appropriate
100: * RoSAPindication structure
101: */
102:
103: static int apdu_proc (sd, papdu, roi, acb, invokeID)
104: int sd;
105: struct type_ROS_ROSEapdus *papdu;
106: register struct RoSAPindication *roi;
107: register struct assocblk *acb;
108: int *invokeID;
109: {
110: int rosap_id;
111:
112: switch (papdu -> offset) {
113: case type_ROS_ROSEapdus_roiv__apdu:
114: roi -> roi_type = ROI_INVOKE;
115: {
116: register struct RoSAPinvoke *rox = &roi -> roi_invoke;
117: register struct type_ROS_ROIVapdu *piv = papdu->un.roiv__apdu;
118:
119: /* if (papdu.un.roiv__apdu->invokeID) */
120: rosap_id = rox -> rox_id = piv -> invokeID -> parm;
121: if (!(rox -> rox_nolinked =
122: !(piv -> optionals & opt_ROS_ROIVapdu_linked__ID)))
123: rox -> rox_linkid = piv -> linked__ID;
124: rox -> rox_op = piv->operation__value -> parm;
125: rox -> rox_args = piv -> argument;
126: }
127: break;
128:
129: case type_ROS_ROSEapdus_rors__apdu:
130: roi -> roi_type = ROI_RESULT;
131: {
132: register struct RoSAPresult *ror = &roi -> roi_result;
133: register struct type_ROS_RORSapdu *pres = papdu->un.rors__apdu;
134:
135: rosap_id = ror -> ror_id = pres -> invokeID -> parm;
136: if (pres -> element_ROS_0) {
137: ror -> ror_op = pres -> element_ROS_0 -> operation__value -> parm;
138: ror -> ror_result = pres -> element_ROS_0 -> result;
139: }/* else what : undefined? */
140: }
141: break;
142:
143: case type_ROS_ROSEapdus_roer__apdu:
144: roi -> roi_type = ROI_ERROR;
145: {
146: register struct RoSAPerror *roe = &roi -> roi_error;
147: register struct type_ROS_ROERapdu *perr = papdu->un.roer__apdu;
148:
149: rosap_id = roe -> roe_id = perr -> invokeID->parm;
150: roe -> roe_error = perr -> error__value -> parm;
151: roe -> roe_param = perr -> parameter;
152: }
153: break;
154:
155: case type_ROS_ROSEapdus_rorj__apdu:
156: roi -> roi_type = ROI_UREJECT;
157: {
158: register struct RoSAPureject *rou = &roi -> roi_ureject;
159: register struct type_ROS_RORJapdu *prej = papdu->un.rorj__apdu;
160:
161: if (prej -> invokeID -> offset == choice_ROS_0_2)
162: rou -> rou_noid = 1;
163: else {
164: rosap_id = rou -> rou_id =
165: prej -> invokeID -> un.choice_ROS_1 -> parm;
166: rou -> rou_noid = 0;
167: }
168:
169: if ((rou -> rou_reason = prob2num(prej -> problem)) == NOTOK) {
170: rou->rou_reason = ROS_PROTOCOL; /* ??? */
171: }
172: }
173: break;
174: }
175:
176: if (invokeID
177: && (papdu -> offset == type_ROS_ROSEapdus_roiv__apdu
178: || (papdu -> offset == type_ROS_ROSEapdus_rorj__apdu
179: && papdu -> un.rorj__apdu -> invokeID -> offset
180: == choice_ROS_0_2)
181: || *invokeID != rosap_id)
182: && acb -> acb_rosindication) {
183: (*acb -> acb_rosindication) (sd = acb -> acb_fd, roi);
184:
185: if (findacblk (sd) != acb)/* still not perfect! */
186: return rosaplose (roi, ROS_DONE, NULLCP, NULLCP);
187: return OK;
188: }
189:
190: return DONE;
191: }
192:
193: /* */
194:
195: /*
196: * Process an OPDU. A seperate function is used for this type of PDU to
197: * simpilfy matters. What is an OPDU - an Old PDU ??
198: */
199:
200: static int opdu_proc (sd, popdu, roi, acb, invokeID)
201: int sd;
202: struct type_ROS_OPDU *popdu;
203: register struct RoSAPindication *roi;
204: register struct assocblk *acb;
205: int *invokeID;
206: {
207: int rosap_id;
208:
209: switch (popdu -> offset) {
210: case type_ROS_OPDU_1:
211: roi -> roi_type = ROI_INVOKE;
212: {
213: register struct RoSAPinvoke *rox = &roi -> roi_invoke;
214: register struct type_ROS_Invoke *piv = popdu->un.choice_ROS_8;
215:
216: rosap_id = rox -> rox_id = piv -> invokeID;
217: rox -> rox_op = piv -> element_ROS_2 -> parm;
218: rox -> rox_args = piv -> argument;
219: }
220: break;
221:
222: case type_ROS_OPDU_2:
223: roi -> roi_type = ROI_RESULT;
224: {
225: register struct RoSAPresult *ror = &roi -> roi_result;
226: register struct type_ROS_ReturnResult *piv
227: = popdu -> un.choice_ROS_9;
228:
229: rosap_id = ror -> ror_id = piv -> invokeID -> parm;
230: /* ror -> ror_op = ?? - can't do this
231: * not fixing this might break programs - time to fix them
232: */
233: ror -> ror_result = piv -> result;
234: }
235: break;
236:
237: case type_ROS_OPDU_3:
238: roi -> roi_type = ROI_ERROR;
239: {
240: register struct RoSAPerror *roe = &roi -> roi_error;
241: register struct type_ROS_ReturnError *per
242: = popdu -> un.choice_ROS_10;
243:
244: rosap_id = roe -> roe_id = per -> invokeID;;
245: roe -> roe_error = per -> element_ROS_3 -> parm;
246: roe -> roe_param = per -> parameter;
247: }
248: break;
249:
250: case type_ROS_OPDU_4:
251: roi -> roi_type = ROI_UREJECT;
252: {
253: register struct RoSAPureject *rou = &roi -> roi_ureject;
254: register struct type_ROS_Reject *prj = popdu->un.choice_ROS_11;
255:
256: if (prj -> invokeID -> offset == choice_ROS_0_2)
257: rou -> rou_noid = 1;
258: else {
259: rosap_id = rou -> rou_id = prj -> invokeID -> un.choice_ROS_1 -> parm;
260: rou -> rou_noid = 0;
261: }
262:
263: if ((rou -> rou_reason = prob2num(prj -> problem)) == NOTOK) {
264: rou -> rou_reason = ROS_PROTOCOL; /* ??? */
265: }
266:
267: }
268: break;
269: }
270:
271: if (invokeID
272: && (popdu -> offset == type_ROS_OPDU_1
273: || (popdu -> offset == type_ROS_OPDU_4
274: && popdu -> un.choice_ROS_11 -> invokeID -> offset
275: == choice_ROS_0_2)
276: || *invokeID != rosap_id)
277: && acb -> acb_rosindication) {
278: (*acb -> acb_rosindication) (sd = acb -> acb_fd, roi);
279:
280: if (findacblk (sd) != acb)/* still not perfect! */
281: return rosaplose (roi, ROS_DONE, NULLCP, NULLCP);
282: return OK;
283: }
284:
285: return DONE;
286: }
287:
288: /* */
289:
290: static int Gprob[] = { ROS_GP_UNRECOG, ROS_GP_MISTYPED, ROS_GP_STRUCT };
291: static int Iprob[] = { ROS_IP_DUP, ROS_IP_UNRECOG, ROS_IP_MISTYPED,
292: ROS_IP_LIMIT, ROS_IP_RELEASE, ROS_IP_UNLINKED,
293: ROS_IP_LINKED, ROS_IP_CHILD };
294: static int RRprob[] = { ROS_RRP_UNRECOG, ROS_RRP_UNEXP, ROS_RRP_MISTYPED };
295: static int REprob[] = { ROS_REP_UNRECOG, ROS_REP_UNEXP, ROS_REP_RECERR,
296: ROS_REP_UNEXPERR, ROS_REP_MISTYPED };
297: /* computes the Number of entries in an array a */
298: #define NENTRIES(a) (sizeof (a)/sizeof (a[0]))
299:
300: /* return the ISODE code from the numbers passed in the data or NOTOK if
301: * it finds an illegal value
302: */
303: static int prob2num (prob)
304: register struct choice_ROS_3 *prob;
305: {
306: register int num;
307:
308: switch (prob -> offset) {
309: case choice_ROS_3_1:
310: if ((num = prob -> un.choice_ROS_4 -> parm) < 0
311: || num >= NENTRIES(Gprob))
312: goto out;
313: num = Gprob[num];
314: break;
315:
316: case choice_ROS_3_2:
317: if ((num = prob -> un.choice_ROS_5 -> parm) < 0
318: || num >= NENTRIES(Iprob))
319: goto out;
320: num = Iprob[num];
321: break;
322:
323: case choice_ROS_3_3:
324: if ((num = prob -> un.choice_ROS_6 -> parm) < 0
325: || num >= NENTRIES(RRprob))
326: goto out;
327: num = RRprob[num];
328: break;
329:
330:
331: case choice_ROS_3_4:
332: if ((num = prob -> un.choice_ROS_7 -> parm) < 0
333: || num >= NENTRIES(REprob))
334: goto out;
335: num = REprob[num];
336: break;
337:
338: default:
339: out: ;
340: return ROS_PROTOCOL; /* What else can we say ?*/
341: }
342:
343: return (num);
344:
345: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.