|
|
1.1 root 1: /* ro2rts.c - ROPM: RtSAP interface */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2rts.c,v 7.1 90/07/01 21:05:46 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/rosap/RCS/ro2rts.c,v 7.1 90/07/01 21:05:46 mrose Exp $
9: *
10: * Based on an TCP-based implementation by George Michaelson of University
11: * College London.
12: *
13: *
14: * $Log: ro2rts.c,v $
15: * Revision 7.1 90/07/01 21:05:46 mrose
16: * pepsy
17: *
18: * Revision 6.0 89/03/18 23:42:10 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 "ROS-types.h"
38: #include "ropkt.h"
39: #include "tailor.h"
40:
41: /* DATA */
42:
43: int rtslose ();
44: int rtsINDICATIONser ();
45:
46: /* bind underlying service */
47:
48: int RoRtService (acb, roi)
49: register struct assocblk *acb;
50: struct RoSAPindication *roi;
51: {
52: if (!(acb -> acb_flags & ACB_RTS))
53: return rosaplose (roi, ROS_OPERATION, NULLCP,
54: "not an association descriptor for ROS on reliable transfer");
55:
56: acb -> acb_putosdu = ro2rtswrite;
57: acb -> acb_rowaitrequest = ro2rtswait;
58: acb -> acb_ready = ro2rtsready;
59: acb -> acb_rosetindications = ro2rtsasync;
60: acb -> acb_roselectmask = ro2rtsmask;
61: acb -> acb_ropktlose = NULLIFP;
62:
63: acb -> acb_flags |= ACB_STICKY;
64:
65: return OK;
66: }
67:
68: /* define vectors for INDICATION events */
69:
70: #define e(i) (indication ? (i) : NULLIFP)
71:
72:
73: /* ARGSUSED */
74:
75: int ro2rtsasync (acb, indication, roi)
76: register struct assocblk *acb;
77: IFP indication;
78: struct RoSAPindication *roi;
79: {
80: struct RtSAPindication rtis;
81: register struct RtSAPabort *rta = &rtis.rti_abort;
82:
83: if (RtSetIndications (acb -> acb_fd, e (rtsINDICATIONser), &rtis)
84: == NOTOK)
85: switch (rta -> rta_reason) {
86: case RTS_WAITING:
87: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
88:
89: default:
90: (void) rtslose (acb, roi, "RtSetIndications", rta);
91: freeacblk (acb);
92: return NOTOK;
93: }
94:
95: if (acb -> acb_rosindication = indication)
96: acb -> acb_flags |= ACB_ASYN;
97: else
98: acb -> acb_flags &= ~ACB_ASYN;
99:
100: return OK;
101: }
102:
103: #undef e
104:
105: /* map association descriptors for select() */
106:
107: /* ARGSUSED */
108:
109: int ro2rtsmask (acb, mask, nfds, roi)
110: register struct assocblk *acb;
111: fd_set *mask;
112: int *nfds;
113: struct RoSAPindication *roi;
114: {
115: struct RtSAPindication rtis;
116: register struct RtSAPabort *rta = &rtis.rti_abort;
117:
118: if (RtSelectMask (acb -> acb_fd, mask, nfds, &rtis) == NOTOK)
119: switch (rta -> rta_reason) {
120: case RTS_WAITING:
121: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
122:
123: default:
124: (void) rtslose (acb, roi, "RtSelectMask", rta);
125: freeacblk (acb);
126: return NOTOK;
127: }
128:
129: return OK;
130: }
131:
132: /* RtSAP interface */
133:
134: #define doRTSdata(a,i,t,r) acb2osdu ((a), (i), (t) -> rtt_data, (r))
135:
136:
137: int ro2rtswait (acb, invokeID, secs, roi)
138: register struct assocblk *acb;
139: int *invokeID,
140: secs;
141: register struct RoSAPindication *roi;
142: {
143: int result;
144: struct RtSAPindication rtis;
145: register struct RtSAPindication *rti = &rtis;
146:
147: if (acb -> acb_apdu) {
148: result = acb2osdu (acb, NULLIP, acb -> acb_apdu, roi);
149: acb -> acb_apdu = NULLPE;
150:
151: return result;
152: }
153: if (acb -> acb_flags & ACB_CLOSING) {
154: acb -> acb_flags |= ACB_FINN;
155: acb -> acb_flags &= ~ACB_CLOSING;
156: if (acb -> acb_flags & ACB_FINISH) {
157: acb -> acb_flags &= ~ACB_FINISH;
158:
159: roi -> roi_type = ROI_FINISH;
160: {
161: register struct AcSAPfinish *acf = &roi -> roi_finish;
162:
163: *acf = acb -> acb_finish; /* struct copy */
164: }
165: }
166: else {
167: roi -> roi_type = ROI_END;
168: {
169: register struct RoSAPend *roe = &roi -> roi_end;
170:
171: bzero ((char *) roe, sizeof *roe);
172: }
173: }
174:
175: return DONE;
176: }
177:
178: for (;;) {
179: switch (result = RtWaitRequest (acb -> acb_fd, secs, rti)) {
180: case NOTOK:
181: return doRTSabort (acb, &rti -> rti_abort, roi);
182:
183: case OK:
184: if ((result = doRTSdata (acb, invokeID, &rti -> rti_transfer,
185: roi)) != OK)
186: return (result != DONE ? result : OK);
187: continue;
188:
189: case DONE:
190: switch (rti -> rti_type) {
191: case RTI_TURN:
192: if (doRTSturn (acb, &rti -> rti_turn, roi) != OK)
193: return result;
194: continue;
195:
196: case RTI_CLOSE:
197: if (doRTSclose (acb, &rti -> rti_close, roi) != OK)
198: return result;
199: continue;
200:
201: case RTI_FINISH:
202: if (doRTSfinish (acb, &rti -> rti_finish, roi) != OK)
203: return result;
204: continue;
205:
206: default:
207: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
208: "unknown indication (0x%x) from rts",
209: rti -> rti_type);
210: break;
211: }
212: break;
213:
214: default:
215: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
216: "unexpected return from RtWaitRequest=%d", result);
217: break;
218: }
219: break;
220: }
221:
222: freeacblk (acb);
223: return NOTOK;
224: }
225:
226: /* */
227:
228: /* ARGSUSED */
229:
230: int ro2rtswrite (acb, pe, fe, priority, roi)
231: register struct assocblk *acb;
232: register PE pe;
233: PE fe;
234: int priority;
235: struct RoSAPindication *roi;
236: {
237: int result;
238: struct RtSAPindication rtis;
239: register struct RtSAPabort *rta = &rtis.rti_abort;
240:
241: #ifdef DEBUG
242: if (rosap_log -> ll_events & LLOG_PDUS)
243: if (acb -> acb_flags & ACB_ACS)
244: pvpdu (rosap_log, print_ROS_ROSEapdus_P, pe, "ROSEapdus", 0);
245: else
246: pvpdu (rosap_log, print_ROS_OPDU_P, pe, "OPDU", 0);
247: #endif
248:
249: result = RtTransferRequest (acb -> acb_fd, pe, NOTOK, &rtis);
250:
251: if (fe)
252: (void) pe_extract (pe, fe);
253: pe_free (pe);
254:
255: if (result == OK)
256: return OK;
257:
258: if (rta -> rta_reason == RTS_TRANSFER)
259: return rosaplose (roi, ROS_APDU, NULLCP, NULLCP);
260:
261: (void) rtslose (acb, roi, "RtTransferRequest", rta);
262:
263: freeacblk (acb);
264: return NOTOK;
265: }
266:
267: /* */
268:
269: static int doRTSturn (acb, rtu, roi)
270: register struct assocblk *acb;
271: register struct RtSAPturn *rtu;
272: register struct RoSAPindication *roi;
273: {
274: struct RtSAPindication rtis;
275: register struct RtSAPindication *rti = &rtis;
276: register struct RtSAPabort *rta = &rti -> rti_abort;
277:
278: if (rtu -> rtu_please) {
279: if (RtGTurnRequest (acb -> acb_fd, rti) == NOTOK)
280: return rtslose (acb, roi, "RtGTurnRequest", rta);
281: }
282:
283: return OK;
284: }
285:
286: /* */
287:
288: /* ARGSUSED */
289:
290: static int doRTSclose (acb, rtc, roi)
291: register struct assocblk *acb;
292: struct RtSAPclose *rtc;
293: register struct RoSAPindication *roi;
294: {
295: if (acb -> acb_flags & ACB_INIT) {
296: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
297: "association management botched");
298: freeacblk (acb);
299: return NOTOK;
300: }
301:
302: roi -> roi_type = ROI_END;
303: {
304: register struct RoSAPend *roe = &roi -> roi_end;
305:
306: bzero ((char *) roe, sizeof *roe);
307: }
308:
309: return DONE;
310: }
311:
312: /* */
313:
314: static int doRTSfinish (acb, acf, roi)
315: register struct assocblk *acb;
316: struct AcSAPfinish *acf;
317: register struct RoSAPindication *roi;
318: {
319: if (acb -> acb_flags & ACB_INIT) {
320: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
321: "association management botched");
322: ACFFREE (acf);
323: freeacblk (acb);
324: return NOTOK;
325: }
326:
327: roi -> roi_type = ROI_FINISH;
328: roi -> roi_finish = *acf; /* struct copy */
329:
330: return DONE;
331: }
332:
333: /* */
334:
335: static int doRTSabort (acb, rta, roi)
336: register struct assocblk *acb;
337: register struct RtSAPabort *rta;
338: register struct RoSAPindication *roi;
339: {
340: if (!rta -> rta_peer) {
341: if (rta -> rta_reason == RTS_TIMER)
342: return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP);
343:
344: (void) rtslose (acb, roi, NULLCP, rta);
345: }
346: else
347: (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP);
348:
349: RTAFREE (rta);
350: acb -> acb_fd = NOTOK;
351: freeacblk (acb);
352:
353: return NOTOK;
354: }
355:
356: /* */
357:
358: static int rtsINDICATIONser (sd, rti)
359: int sd;
360: register struct RtSAPindication *rti;
361: {
362: int result;
363: IFP handler;
364: register struct assocblk *acb;
365: struct RoSAPindication rois;
366: register struct RoSAPindication *roi = &rois;
367:
368: if ((acb = findacblk (sd)) == NULL)
369: return;
370:
371: handler = acb -> acb_rosindication;
372:
373: switch (rti -> rti_type) {
374: case RTI_TURN:
375: result = doRTSturn (acb, &rti -> rti_turn, roi);
376: break;
377:
378: case RTI_TRANSFER:
379: result = doRTSdata (acb, NULLIP, &rti -> rti_transfer, roi);
380: break;
381:
382: case RTI_ABORT:
383: result = doRTSabort (acb, &rti -> rti_abort, roi);
384: break;
385:
386: case RTI_CLOSE:
387: result = doRTSclose (acb, &rti -> rti_close, roi);
388: break;
389:
390: case RTI_FINISH:
391: result = doRTSfinish (acb, &rti -> rti_finish, roi);
392: break;
393:
394: default:
395: result = ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
396: "unknown indication (0x%x) from rts",
397: rti -> rti_type);
398: freeacblk (acb);
399: break;
400: }
401:
402: if (result != OK)
403: (*handler) (sd, roi);
404: }
405:
406: /* */
407:
408: int ro2rtsready (acb, priority, roi)
409: register struct assocblk *acb;
410: int priority;
411: struct RoSAPindication *roi;
412: {
413: int result;
414: struct RtSAPindication rtis;
415: register struct RtSAPindication *rti = &rtis;
416: register struct RtSAPabort *rta = &rti -> rti_abort;
417:
418: if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING))
419: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
420:
421: if (RtPTurnRequest (acb -> acb_fd, priority, rti) == NOTOK) {
422: (void) rtslose (acb, roi, "RtPTurnRequest", rta);
423: goto out;
424: }
425:
426: do {
427: switch (result = RtWaitRequest (acb -> acb_fd, NOTOK, rti)) {
428: case NOTOK:
429: return doRTSabort (acb, &rti -> rti_abort, roi);
430:
431: case OK:
432: acb -> acb_apdu = rti -> rti_transfer.rtt_data;
433: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
434:
435: case DONE:
436: switch (rti -> rti_type) {
437: case RTI_TURN:
438: if (doRTSturn (acb, &rti -> rti_turn, roi) != OK)
439: return result;
440: continue;
441:
442: case RTI_CLOSE:
443: switch (doRTSclose (acb, &rti -> rti_close, roi)) {
444: case NOTOK:
445: return NOTOK;
446:
447: case OK:
448: break;
449:
450: case DONE:
451: acb -> acb_flags |= ACB_CLOSING;
452: acb -> acb_flags &= ~ACB_FINN;
453: return rosaplose (roi, ROS_WAITING, NULLCP,
454: NULLCP);
455: }
456: continue;
457:
458: case RTI_FINISH:
459: switch (doRTSfinish (acb, &rti -> rti_finish, roi)) {
460: case NOTOK:
461: return NOTOK;
462:
463: case OK:
464: break;
465:
466: case DONE:
467: acb -> acb_flags |= ACB_FINISH | ACB_CLOSING;
468: acb -> acb_flags &= ~ACB_FINN;
469: /* struct copy */
470: acb -> acb_finish = roi -> roi_finish;
471: return rosaplose (roi, ROS_WAITING, NULLCP,
472: NULLCP);
473: }
474: continue;
475:
476: default:
477: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
478: "unknown indication (0x%x) from rts",
479: rti -> rti_type);
480: break;
481: }
482: goto out;
483:
484: default:
485: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
486: "unexpected return from RtWaitRequest=%d", result);
487: goto out;
488: }
489: }
490: while (!(acb -> acb_flags & ACB_TURN));
491:
492: return OK;
493:
494: out: ;
495: freeacblk (acb);
496: return NOTOK;
497: }
498:
499: /* */
500:
501: static int rtslose (acb, roi, event, rta)
502: register struct assocblk *acb;
503: register struct RoSAPindication *roi;
504: char *event;
505: register struct RtSAPabort *rta;
506: {
507: int reason;
508: char *cp,
509: buffer[BUFSIZ];
510:
511: if (event)
512: SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP,
513: (rta -> rta_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
514: RtErrString (rta -> rta_reason), rta -> rta_cc, rta -> rta_cc,
515: rta -> rta_data));
516:
517: cp = "";
518: switch (rta -> rta_reason) {
519: case RTS_ADDRESS:
520: reason = ROS_ADDRESS;
521: break;
522:
523: case RTS_REFUSED:
524: reason = ROS_REFUSED;
525: break;
526:
527: case RTS_CONGEST:
528: reason = ROS_CONGEST;
529: break;
530:
531: default:
532: (void) sprintf (cp = buffer, " (%s at rts)",
533: RtErrString (rta -> rta_reason));
534: case RTS_SESSION:
535: reason = ROS_RTS;
536: break;
537: }
538:
539: if (rta -> rta_cc > 0)
540: return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s",
541: rta -> rta_cc, rta -> rta_cc, rta -> rta_data, cp);
542: else
543: return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
544: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.