|
|
1.1 root 1: /* isod.c - "minimal" ISODE server for testing */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/support/RCS/isod.c,v 7.1 90/07/01 21:07:50 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/support/RCS/isod.c,v 7.1 90/07/01 21:07:50 mrose Exp $
9: *
10: *
11: * $Log: isod.c,v $
12: * Revision 7.1 90/07/01 21:07:50 mrose
13: * pepsy
14: *
15: * Revision 7.0 89/11/23 22:27:27 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include <stdio.h>
32: #include <varargs.h>
33: #include "rosap.h"
34: #include "rtsap.h"
35: #include "acsap.h"
36: #include "psap2.h"
37: #include "ssap.h"
38: #include "tsap.h"
39: #include "isoservent.h"
40: #include "tailor.h"
41: #include "OACS-types.h"
42:
43: /* DATA */
44:
45: static int debug = 0;
46: static int isacs = 0;
47: static int isrts = 0;
48:
49: static LLog _pgm_log = {
50: "isod.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
51: LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
52: };
53: LLog *pgm_log = &_pgm_log;
54:
55: static char *myname = "isod";
56:
57:
58: static enum mode { echo, sink, XXX } mymode = XXX;
59:
60: struct dispatch {
61: char *ds_entity;
62:
63: enum mode ds_mode;
64: };
65:
66:
67: void adios (), advise ();
68:
69:
70: void ts_adios (), ts_advise ();
71: int ts_dataindication (), ts_discindication ();
72:
73: static struct dispatch ts_dispatches[] = {
74: "echo", echo,
75: "sink", sink,
76:
77: NULLCP, XXX
78: };
79:
80:
81: void ss_adios (), ss_advise ();
82: int ss_dataindication (), ss_tokenindication (), ss_syncindication (),
83: ss_actindication (), ss_reportindication (), ss_finishindication (),
84: ss_abortindication ();
85:
86: static struct dispatch *ss_dispatches = ts_dispatches;
87:
88:
89: void ps_adios (), ps_advise ();
90: int ps_dataindication (), ps_tokenindication (), ps_syncindication (),
91: ps_actindication (), ps_reportindication (), ps_finishindication (),
92: ps_abortindication ();
93:
94: static struct dispatch *ps_dispatches = ts_dispatches;
95:
96:
97: void acs_adios (), acs_advise ();
98:
99: static struct dispatch acs_dispatches[] = {
100: "isode echo", echo,
101: "isode sink", sink,
102:
103: NULLCP, XXX
104: };
105:
106:
107: void rts_adios (), rts_advise ();
108: int rts_indication ();
109:
110: static struct dispatch rts_dispatches[] = {
111: "echo", echo,
112: "sink", sink,
113: "ros_echo", echo,
114: "ros_sink", sink,
115:
116: NULLCP, XXX
117: };
118:
119: static struct dispatch rtse_dispatches[] = {
120: "isode rtse echo", echo,
121: "isode rtse sink", sink,
122: "isode ros_echo", echo,
123: "isode ros_sink", sink,
124:
125: NULLCP, XXX
126: };
127:
128: static PE apdupe = NULLPE;
129:
130:
131: void ros_adios (), ros_advise ();
132: int ros_indication ();
133:
134: static struct dispatch *ros_dispatches = ts_dispatches;
135:
136: static PE nullpe = NULLPE;
137:
138:
139: extern int errno;
140:
141: /* MAIN */
142:
143: /* ARGSUSED */
144:
145: main (argc, argv, envp)
146: int argc;
147: char **argv,
148: **envp;
149: {
150: register char *cp;
151:
152: if (myname = rindex (argv[0], '/'))
153: myname++;
154: if (myname == NULL || *myname == NULL)
155: myname = argv[0];
156:
157: isodetailor (myname, 0);
158: if (debug = isatty (fileno (stderr)))
159: ll_dbinit (pgm_log, myname);
160: else
161: ll_hdinit (pgm_log, myname);
162:
163: advise (LLOG_NOTICE, NULLCP, "starting");
164:
165: if (cp = rindex (*argv, '.'))
166: *cp++ = NULL;
167:
168: /* cheat! should do this after calling the init function (sigh!) */
169: if (argc > 1 && strcmp (argv[1], "-rtse") == 0)
170: isacs++;
171:
172: if (cp == NULL || strcmp (cp, "tsap") == 0)
173: ts_main (argc, argv);
174: else
175: if (strcmp (cp, "ssap") == 0)
176: ss_main (argc, argv);
177: else
178: if (strcmp (cp, "psap") == 0)
179: ps_main (argc, argv);
180: else
181: if (strcmp (cp, "acsap") == 0) {
182: isacs++;
183: ps_main (argc, argv);
184: }
185: else
186: if (strcmp (cp, "rtsap") == 0) {
187: isrts++;
188: rts_main (argc, argv);
189: }
190: else
191: if (strcmp (cp, "rosap") == 0)
192: ros_main (argc, argv);
193: else
194: adios (NULLCP, "unknown provider: \"%s\"", cp);
195:
196: exit (0); /* NOTREACHED */
197: }
198:
199: /* TSAP */
200:
201: static int ts_main (argc, argv)
202: int argc;
203: char **argv;
204: {
205: int async,
206: sd;
207: char buffer[BUFSIZ];
208: register struct dispatch *ds;
209: register struct isoservent *is;
210: struct TSAPstart tss;
211: register struct TSAPstart *ts = &tss;
212: struct TSAPdata txs;
213: register struct TSAPdata *tx = &txs;
214: struct TSAPdisconnect tds;
215: register struct TSAPdisconnect *td = &tds;
216:
217: if (TInit (argc, argv, ts, td) == NOTOK)
218: ts_adios (td, "(T)initialization fails");
219: advise (LLOG_NOTICE, NULLCP,
220: "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",
221: ts -> ts_sd,
222: taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called),
223: ts -> ts_expedited, ts -> ts_tsdusize);
224: #ifdef DEBUG
225: if (ts -> ts_cc > 0)
226: advise (LLOG_DEBUG, NULLCP, "greetings: %d octets", ts -> ts_cc);
227: #endif
228:
229: sd = ts -> ts_sd;
230:
231: if (is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector,
232: ts -> ts_called.ta_selectlen))
233: for (ds = ts_dispatches; ds -> ds_entity; ds++)
234: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
235: mymode = ds -> ds_mode;
236: break;
237: }
238:
239: async = 0;
240: for (argv++; *argv; argv++) {
241: if (strcmp (*argv, "-async") == 0) {
242: async++;
243: continue;
244: }
245: if (strcmp (*argv, "-sync") == 0) {
246: async = 0;
247: continue;
248: }
249:
250: advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
251: }
252:
253: switch (mymode) {
254: case echo:
255: case sink:
256: if (TConnResponse (sd, NULLTA, ts -> ts_expedited,
257: mymode == echo ? ts -> ts_data : NULLCP,
258: mymode == echo ? ts -> ts_cc : 0, NULLQOS, td) == NOTOK)
259: ts_adios (td, "T-CONNECT.RESPONSE");
260: break;
261:
262: default:
263: (void) strcpy (buffer, "entity unknown or unavailable");
264: if (TDiscRequest (sd, buffer, strlen (buffer) + 1, td) == NOTOK)
265: ts_adios (td, "T-DISCONNECT.REQUEST");
266: advise (LLOG_NOTICE, NULLCP, "rejected");
267: exit (1);
268: }
269:
270: if (async) {
271: if (TSetIndications (sd, ts_dataindication, ts_discindication, td)
272: == NOTOK)
273: ts_adios (td, "set ASYNC fails");
274:
275: for (;;)
276: pause ();
277: }
278:
279: for (;;) {
280: if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
281: ts_discindication (sd, td);
282:
283: ts_dataindication (sd, tx);
284: }
285: }
286:
287: /* */
288:
289: static int ts_dataindication (sd, tx)
290: int sd;
291: register struct TSAPdata *tx;
292: {
293: struct TSAPdisconnect tds;
294: register struct TSAPdisconnect *td = &tds;
295:
296: if (mymode == echo) {
297: register char *p = qb2str (&tx -> tx_qbuf);
298:
299: if ((tx -> tx_expedited
300: ? TExpdRequest (sd, p, tx -> tx_cc, td)
301: : TDataRequest (sd, p, tx -> tx_cc, td))
302: == NOTOK) {
303: if (td -> td_reason == DR_NORMAL)
304: ts_discindication (sd, td);
305:
306: ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST"
307: : "T-DATA.REQUEST");
308: }
309:
310: free (p);
311: }
312:
313: TXFREE (tx);
314: }
315:
316: /* */
317:
318: /* ARGSUSED */
319:
320: static int ts_discindication (sd, td)
321: int sd;
322: register struct TSAPdisconnect *td;
323: {
324: if (td -> td_reason != DR_NORMAL)
325: ts_adios (td, "T-DISCONNECT.INDICATION");
326:
327: if (td -> td_cc > 0)
328: ts_advise (td, "T-DISCONNECT.INDICATION");
329: else
330: advise (LLOG_NOTICE, NULLCP, "T-DISCONNECT.INDICATION");
331:
332: exit (0);
333: }
334:
335: /* */
336:
337: static void ts_adios (td, event)
338: register struct TSAPdisconnect *td;
339: char *event;
340: {
341: ts_advise (td, event);
342:
343: _exit (1);
344: }
345:
346:
347: static void ts_advise (td, event)
348: register struct TSAPdisconnect *td;
349: char *event;
350: {
351: char buffer[BUFSIZ];
352:
353: if (td -> td_cc > 0)
354: (void) sprintf (buffer, "[%s] %*.*s",
355: TErrString (td -> td_reason),
356: td -> td_cc, td -> td_cc, td -> td_data);
357: else
358: (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
359:
360: advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
361: }
362:
363: /* SSAP */
364:
365: #define RMASK \
366: "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
367: \07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
368:
369: #define TMASK "\020\01DATA\03SYNC\05ACTIVITY\07RELEASE"
370:
371:
372: #define dotoken(requires,shift,bit,type) \
373: { \
374: if (requirements & requires) \
375: switch (ss -> ss_settings & (ST_MASK << shift)) { \
376: case ST_CALL_VALUE << shift: \
377: advise (LLOG_DEBUG, NULLCP, "%s token: choice", type); \
378: ss -> ss_settings &= ~(ST_MASK << shift); \
379: ss -> ss_settings |= ST_INIT_VALUE << shift; \
380: break; \
381: \
382: case ST_INIT_VALUE: \
383: advise (LLOG_DEBUG, NULLCP, "%s token: initiator", type); \
384: break; \
385: \
386: case ST_RESP_VALUE: \
387: advise (LLOG_DEBUG, NULLCP, "%s token: responder", type); \
388: owned |= bit; \
389: break; \
390: \
391: default: \
392: adios (NULLCP, "%s token: reserved", type); \
393: break; \
394: } \
395: }
396:
397:
398: static int requirements = 0;
399: static int owned = 0;
400:
401: static struct SSAPdata hxs;
402: static struct SSAPdata *hx = &hxs;
403:
404: /* */
405:
406: static int ss_main (argc, argv)
407: int argc;
408: char **argv;
409: {
410: int async,
411: result,
412: sd;
413: char buffer[BUFSIZ];
414: register struct dispatch *ds;
415: register struct isoservent *is;
416: struct SSAPstart sss;
417: register struct SSAPstart *ss = &sss;
418: struct SSAPdata sxs;
419: register struct SSAPdata *sx = &sxs;
420: struct SSAPindication sis;
421: register struct SSAPindication *si = &sis;
422: register struct SSAPabort *sa = &si -> si_abort;
423:
424: if (SInit (argc, argv, ss, si) == NOTOK)
425: ss_adios (sa, "(S)initialization fails");
426: advise (LLOG_NOTICE, NULLCP,
427: "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>",
428: ss -> ss_sd, sprintref (&ss -> ss_connect),
429: saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called),
430: sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn,
431: ss -> ss_ssdusize);
432: #ifdef DEBUG
433: if (ss -> ss_cc > 0)
434: advise (LLOG_DEBUG, NULLCP, "greetings: %d octets", ss -> ss_cc);
435: #endif
436:
437: sd = ss -> ss_sd;
438: ss -> ss_requirements &= SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
439: | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
440: | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
441: if ((ss -> ss_requirements & SR_HALFDUPLEX)
442: && (ss -> ss_requirements & SR_DUPLEX))
443: ss -> ss_requirements &= ~SR_DUPLEX;
444: requirements = ss -> ss_requirements;
445: advise (LLOG_DEBUG, NULLCP, "new requirements: %s",
446: sprintb (ss -> ss_requirements, RMASK));
447: dotokens ();
448: advise (LLOG_DEBUG, NULLCP, "initial tokens: %s", sprintb (owned, TMASK));
449: if (!(ss -> ss_requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)))
450: ss -> ss_isn = SERIAL_NONE;
451:
452: if (is = getisoserventbyselector ("ssap", ss -> ss_called.sa_selector,
453: ss -> ss_called.sa_selectlen))
454: for (ds = ss_dispatches; ds -> ds_entity; ds++)
455: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
456: mymode = ds -> ds_mode;
457: break;
458: }
459:
460: async = 0;
461: for (argv++; *argv; argv++) {
462: if (strcmp (*argv, "-async") == 0) {
463: async++;
464: continue;
465: }
466: if (strcmp (*argv, "-sync") == 0) {
467: async = 0;
468: continue;
469: }
470:
471: advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
472: }
473:
474: switch (mymode) {
475: case echo:
476: case sink:
477: if (SConnResponse (sd, &ss -> ss_connect, NULLSA,
478: SC_ACCEPT, ss -> ss_requirements, ss -> ss_settings,
479: ss -> ss_isn, mymode == echo ? ss -> ss_data : NULLCP,
480: mymode == echo ? ss -> ss_cc : 0, si) == NOTOK)
481: ss_adios (sa, "S-CONNECT.RESPONSE (accept)");
482: break;
483:
484: default:
485: (void) strcpy (buffer, "entity unknown or unavailable");
486: if (SConnResponse (sd, &ss -> ss_connect, NULLSA,
487: SC_REJECTED, 0, 0, SERIAL_NONE, buffer,
488: strlen (buffer + 1), si)
489: == NOTOK)
490: ss_adios (sa, "S-CONNECT.RESPONSE (reject)");
491: advise (LLOG_NOTICE, NULLCP, "rejected");
492: exit (1);
493: }
494:
495: if (async) {
496: if (SSetIndications (sd, ss_dataindication, ss_tokenindication,
497: ss_syncindication, ss_actindication, ss_reportindication,
498: ss_finishindication, ss_abortindication, si) == NOTOK)
499: ss_adios (sa, "set ASYNC fails");
500:
501: for (;;)
502: pause ();
503: }
504:
505: for (;;)
506: switch (result = SReadRequest (sd, sx, NOTOK, si)) {
507: case NOTOK:
508: ss_abortindication (sd, sa);
509:
510: case OK:
511: ss_dataindication (sd, sx);
512: break;
513:
514: case DONE:
515: switch (si -> si_type) {
516: case SI_TOKEN:
517: ss_tokenindication (sd, &si -> si_token);
518: break;
519:
520: case SI_SYNC:
521: ss_syncindication (sd, &si -> si_sync);
522: break;
523:
524: case SI_ACTIVITY:
525: ss_actindication (sd, &si -> si_activity);
526: break;
527:
528: case SI_REPORT:
529: ss_reportindication (sd, &si -> si_report);
530: break;
531:
532: case SI_FINISH:
533: ss_finishindication (sd, &si -> si_finish);
534: break;
535:
536: default:
537: adios (NULLCP, "unknown indication type=0x%x",
538: si -> si_type);
539: }
540: break;
541:
542: default:
543: adios (NULLCP, "unknown return from SReadRequest=%d", result);
544: }
545: }
546:
547: #undef dotoken
548:
549: /* */
550:
551: static int ss_dataindication (sd, sx)
552: int sd;
553: register struct SSAPdata *sx;
554: {
555: char *p,
556: buffer[BUFSIZ];
557: struct SSAPindication sis;
558: register struct SSAPindication *si = &sis;
559: register struct SSAPabort *sa = &si -> si_abort;
560:
561: #ifdef DEBUG
562: switch (sx -> sx_type) {
563: case SX_NORMAL:
564: advise (LLOG_DEBUG, NULLCP, "normal data, %d bytes", sx -> sx_cc);
565: break;
566:
567: case SX_EXPEDITED:
568: advise (LLOG_DEBUG, NULLCP, "expedited data, %d bytes",
569: sx -> sx_cc);
570: break;
571:
572: case SX_TYPED:
573: advise (LLOG_DEBUG, NULLCP, "typed data, %d bytes", sx -> sx_cc);
574: break;
575:
576: case SX_CAPDIND:
577: advise (LLOG_DEBUG, NULLCP, "capability data, %d bytes",
578: sx -> sx_cc);
579: break;
580:
581: case SX_CAPDCNF:
582: advise (LLOG_DEBUG, NULLCP, "capability data ack, %d bytes",
583: sx -> sx_cc);
584:
585: default:
586: advise (LLOG_DEBUG, NULLCP,
587: "unknown data indication type=0x%x, %d bytes",
588: sx -> sx_type, sx -> sx_cc);
589: }
590: #endif
591:
592: p = NULL;
593:
594: switch (sx -> sx_type) {
595: case SX_NORMAL:
596: if (mymode == sink)
597: break;
598: if (requirements & SR_HALFDUPLEX) {
599: if (hx -> sx_cc > 0) {
600: (void) strcpy (buffer, "protocol screw-up");
601: if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
602: ss_adios (sa, "S-U-ABORT.REQUEST");
603: else
604: adios (NULLCP, "protocol screw-up");
605: }
606: else {
607: *hx = *sx; /* struct copy */
608: hx -> sx_qbuf.qb_forw -> qb_back =
609: hx -> sx_qbuf.qb_back -> qb_forw = &hx -> sx_qbuf;
610: bzero ((char *) sx, sizeof *sx);
611: sx -> sx_qbuf.qb_forw =
612: sx -> sx_qbuf.qb_back = &sx -> sx_qbuf;
613: if (!(owned & ST_DAT_TOKEN)
614: && SPTokenRequest (sd, ST_DAT_TOKEN, NULLCP,
615: 0, si) == NOTOK)
616: ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
617: }
618: }
619: else
620: if (SDataRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
621: si) == NOTOK)
622: ss_adios (sa, "S-DATA.REQUEST");
623: break;
624:
625: case SX_EXPEDITED:
626: if (mymode == sink)
627: break;
628: if (SExpdRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
629: si) == NOTOK)
630: ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
631: break;
632:
633: case SX_TYPED:
634: if (mymode == sink)
635: break;
636: if (STypedRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
637: si) == NOTOK)
638: ss_adios (sa, "S-TYPED-DATA.REQUEST");
639: break;
640:
641: case SX_CAPDIND:
642: if (SCapdResponse (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
643: si) == NOTOK)
644: ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
645: break;
646:
647: case SX_CAPDCNF:
648: adios (NULLCP, "got capability data response");
649:
650: default:
651: adios (NULLCP, "unknown data indication type=0x%x", sx -> sx_type);
652: }
653:
654: SXFREE (sx);
655: if (p)
656: free (p);
657: }
658:
659: /* */
660:
661: static int ss_tokenindication (sd, st)
662: int sd;
663: register struct SSAPtoken *st;
664: {
665: struct SSAPindication sis;
666: register struct SSAPindication *si = &sis;
667: register struct SSAPabort *sa = &si -> si_abort;
668:
669: #ifdef DEBUG
670: advise (LLOG_DEBUG, NULLCP, "%s tokens: %s, %d bytes",
671: st -> st_type == ST_PLEASE ? "please"
672: : st -> st_type == ST_GIVE ? "give" : "control",
673: sprintb ((int) st -> st_tokens, TMASK), st -> st_cc);
674: #endif
675:
676: switch (st -> st_type) {
677: case ST_GIVE:
678: case ST_CONTROL:
679: owned = st -> st_owned;
680: break;
681:
682: case ST_PLEASE:
683: break;
684:
685: default:
686: adios (NULLCP, "unknown token indication type=0x%x",
687: st -> st_type);
688: }
689:
690: if ((owned & ST_DAT_TOKEN) && hx -> sx_cc > 0) {
691: char *p;
692:
693: if (SDataRequest (sd, p = qb2str (&hx -> sx_qbuf), hx -> sx_cc, si)
694: == NOTOK)
695: ss_adios (sa, "S-DATA.REQUEST");
696: SXFREE (hx);
697: free (p);
698: bzero ((char *) hx, sizeof *hx);
699: hx -> sx_qbuf.qb_forw =
700: hx -> sx_qbuf.qb_back = &hx -> sx_qbuf;
701: }
702:
703: switch (st -> st_type) {
704: case ST_GIVE:
705: break;
706:
707: default:
708: if (SGTokenRequest (sd, (int) st -> st_tokens, si) == NOTOK)
709: ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
710: else
711: owned &= ~st -> st_tokens;
712: break;
713: }
714:
715: STFREE (st);
716: }
717:
718: /* */
719:
720: static int ss_syncindication (sd, sn)
721: int sd;
722: register struct SSAPsync *sn;
723: {
724: struct SSAPindication sis;
725: register struct SSAPindication *si = &sis;
726: register struct SSAPabort *sa = &si -> si_abort;
727:
728: #ifdef DEBUG
729: switch (sn -> sn_type) {
730: case SN_MAJORIND:
731: advise (LLOG_DEBUG, NULLCP, "majorsync indication %d, %d bytes",
732: sn -> sn_ssn, sn -> sn_cc);
733: break;
734:
735: case SN_MAJORCNF:
736: advise (LLOG_DEBUG, NULLCP, "majorsync confirmation %d, %d bytes",
737: sn -> sn_ssn, sn -> sn_cc);
738: break;
739:
740: case SN_MINORIND:
741: advise (LLOG_DEBUG, NULLCP, "minorsync indication %d%s, %d bytes",
742: sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
743: ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
744: break;
745:
746: case SN_MINORCNF:
747: advise (LLOG_DEBUG, NULLCP, "minorsync confirmation %d, %d bytes",
748: sn -> sn_ssn, sn -> sn_cc);
749: break;
750:
751: case SN_RESETIND:
752: advise (LLOG_DEBUG, NULLCP,
753: "resync indication type=%d %d, %d bytes",
754: sn -> sn_options, sn -> sn_ssn, sn -> sn_cc);
755: break;
756:
757: case SN_RESETCNF:
758: advise (LLOG_DEBUG, NULLCP, "resync confirmation %d, %d bytes",
759: sn -> sn_ssn, sn -> sn_cc);
760: break;
761:
762: default:
763: advise (LLOG_DEBUG, NULLCP,
764: "unknown sync indication=0x%x, ssn=%d, %d bytes",
765: sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
766: break;
767: }
768: #endif
769:
770: switch (sn -> sn_type) {
771: case SN_MAJORIND:
772: if (SMajSyncResponse (sd,
773: mymode == echo ? sn -> sn_data : NULL,
774: mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
775: ss_adios (sa, "S-MAJOR-SYNC.RESPONSE");
776: break;
777:
778: case SN_MAJORCNF:
779: adios (NULLCP, "got majorsync confirmation");
780:
781: case SN_MINORIND:
782: if (sn -> sn_options == SYNC_CONFIRM)
783: if (SMinSyncResponse (sd, sn -> sn_ssn,
784: mymode == echo ? sn -> sn_data : NULL,
785: mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
786: ss_adios (sa, "S-MINOR-SYNC.RESPONSE");
787: break;
788:
789: case SN_MINORCNF:
790: adios (NULLCP, "got minorsync confirmation");
791:
792: case SN_RESETIND:
793: #define dotoken(requires,shift,bit,type) \
794: { \
795: if (requirements & requires) \
796: switch (sn -> sn_settings & (ST_MASK << shift)) { \
797: case ST_CALL_VALUE << shift: \
798: sn -> sn_settings &= ~(ST_MASK << shift); \
799: sn -> sn_settings |= ST_RESP_VALUE << shift; \
800: case ST_RESP_VALUE << shift: \
801: owned |= bit; \
802: break; \
803: \
804: case ST_INIT_VALUE << shift: \
805: owned &= ~bit; \
806: break; \
807: \
808: default: \
809: adios (NULLCP, "%s token: reserved", type); \
810: break; \
811: } \
812: }
813: dotokens ();
814: #undef dotoken
815: if (SReSyncRequest (sd, SYNC_ABANDON, SERIAL_NONE,
816: sn -> sn_settings,
817: mymode == echo ? sn -> sn_data : NULL,
818: mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
819: ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
820: break;
821:
822: case SN_RESETCNF:
823: break;
824:
825: default:
826: adios (NULLCP, "unknown sync indication type=0x%x", sn -> sn_type);
827: }
828:
829: SNFREE (sn);
830: }
831:
832: /* */
833:
834: static int ss_actindication (sd, sv)
835: int sd;
836: register struct SSAPactivity *sv;
837: {
838: struct SSAPindication sis;
839: register struct SSAPindication *si = &sis;
840: register struct SSAPabort *sa = &si -> si_abort;
841:
842: #ifdef DEBUG
843: switch (sv -> sv_type) {
844: case SV_START:
845: advise (LLOG_DEBUG, NULLCP,
846: "activity start indication: %*.*s, %d bytes",
847: sv -> sv_id.sd_len, sv -> sv_id.sd_len,
848: sv -> sv_id.sd_data, sv -> sv_cc);
849: break;
850:
851: case SV_RESUME:
852: advise (LLOG_DEBUG, NULLCP,
853: "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
854: sv -> sv_id.sd_len, sv -> sv_id.sd_len,
855: sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
856: sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
857: sprintref (&sv -> sv_connect), sv -> sv_ssn, sv -> sv_cc);
858: break;
859:
860: case SV_INTRIND:
861: advise (LLOG_DEBUG, NULLCP,
862: "activity interrupt indication %d, %d bytes",
863: sv -> sv_reason, sv -> sv_cc);
864: break;
865:
866: case SV_INTRCNF:
867: advise (LLOG_DEBUG, NULLCP,
868: "activity interrupt confirmation, %d bytes", sv -> sv_cc);
869: break;
870:
871: case SV_DISCIND:
872: advise (LLOG_DEBUG, NULLCP,
873: "activity discard indication %d, %d bytes",
874: sv -> sv_reason, sv -> sv_cc);
875: break;
876:
877: case SV_DISCCNF:
878: advise (LLOG_DEBUG, NULLCP,
879: "activity discard confirmation, %d bytes", sv -> sv_cc);
880: break;
881:
882: case SV_ENDIND:
883: advise (LLOG_DEBUG, NULLCP, "activity end indication %d, %d bytes",
884: sv -> sv_ssn, sv -> sv_cc);
885: break;
886:
887: case SV_ENDCNF:
888: advise (LLOG_DEBUG, NULLCP, "activity end confirmation, %d bytes",
889: sv -> sv_cc);
890: break;
891:
892: default:
893: advise (LLOG_DEBUG, NULLCP,
894: "unknown activity indication=0x%x, %d bytes",
895: sv -> sv_type, sv -> sv_cc);
896: break;
897: }
898: #endif
899:
900: switch (sv -> sv_type) {
901: case SV_START:
902: case SV_RESUME:
903: break;
904:
905: case SV_INTRIND:
906: if (SActIntrResponse (sd, si) == NOTOK)
907: ss_adios (sa, "S-ACTIVITY-INTERRUPT.RESPONSE");
908: owned = 0;
909: break;
910:
911: case SV_INTRCNF:
912: adios (NULLCP, "got activity interrupt confirmation");
913:
914: case SV_DISCIND:
915: if (SActDiscResponse (sd, si) == NOTOK)
916: ss_adios (sa, "S-ACTIVITY-DISCARD.RESPONSE");
917: owned = 0;
918: break;
919:
920: case SV_DISCCNF:
921: adios (NULLCP, "got activity discard confirmation");
922:
923: case SV_ENDIND:
924: if (SActEndResponse (sd, mymode == echo ? sv -> sv_data : NULLCP,
925: mymode == echo ? sv -> sv_cc : 0, si) == NOTOK)
926: ss_adios (sa, "S-ACTIVITY-END.RESPONSE");
927: break;
928:
929: case SV_ENDCNF:
930: adios (NULLCP, "got activity end confirmation");
931:
932: default:
933: adios (NULLCP, "unknown activity indication=0x%x", sv -> sv_type);
934: }
935:
936: SVFREE (sv);
937: }
938:
939: /* */
940:
941: static int ss_reportindication (sd, sp)
942: int sd;
943: struct SSAPreport *sp;
944: {
945: struct SSAPindication sis;
946: register struct SSAPindication *si = &sis;
947: register struct SSAPabort *sa = &si -> si_abort;
948:
949: #ifdef DEBUG
950: advise (LLOG_DEBUG, NULLCP, "%s report %d, %d bytes",
951: sp -> sp_peer ? "user" : "provider", sp -> sp_reason, sp -> sp_cc);
952: #endif
953:
954: if (requirements & SR_DAT_EXISTS) {
955: if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
956: ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
957: else
958: owned &= ~ST_DAT_TOKEN;
959: #ifdef DEBUG
960: advise (LLOG_DEBUG, NULLCP, "cleared");
961: #endif
962: }
963: else
964: if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
965: ss_adios (sa, "S-U-ABORT.REQUEST");
966: else
967: adios (NULLCP, "aborted");
968:
969: SPFREE (sp);
970: }
971:
972: /* */
973:
974: static int ss_finishindication (sd, sf)
975: int sd;
976: register struct SSAPfinish *sf;
977: {
978: struct SSAPindication sis;
979: register struct SSAPindication *si = &sis;
980: register struct SSAPabort *sa = &si -> si_abort;
981:
982: if (sf -> sf_cc > 0)
983: advise (LLOG_NOTICE, NULLCP, "S-RELEASE.INDICATION: %d bytes",
984: sf -> sf_cc);
985: else
986: advise (LLOG_NOTICE, NULLCP, "S-RELEASE.INDICATION");
987:
988: if (SRelResponse (sd, SC_ACCEPT, mymode == echo ? sf -> sf_data : NULL,
989: mymode == echo ? sf -> sf_cc : 0, si) == NOTOK)
990: ss_adios (sa, "S-RELEASE.RESPONSE");
991:
992: SFFREE (sf);
993:
994: exit (0);
995: }
996:
997:
998: /* ARGSUSED */
999:
1000: static int ss_abortindication (sd, sa)
1001: int sd;
1002: register struct SSAPabort *sa;
1003: {
1004: if (!sa -> sa_peer)
1005: ss_adios (sa, "S-P-ABORT.INDICATION");
1006:
1007: if (sa -> sa_cc > 0)
1008: ss_advise (sa, "S-U-ABORT.INDICATION");
1009: else
1010: advise (LLOG_NOTICE, NULLCP, "S-U-ABORT.INDICATION");
1011:
1012: exit (1);
1013: }
1014:
1015: /* */
1016:
1017: static void ss_adios (sa, event)
1018: register struct SSAPabort *sa;
1019: char *event;
1020: {
1021: ss_advise (sa, event);
1022:
1023: _exit (1);
1024: }
1025:
1026:
1027: static void ss_advise (sa, event)
1028: register struct SSAPabort *sa;
1029: char *event;
1030: {
1031: char buffer[BUFSIZ];
1032:
1033: if (sa -> sa_cc > 0)
1034: (void) sprintf (buffer, "[%s] %*.*s",
1035: SErrString (sa -> sa_reason),
1036: sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
1037: else
1038: (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
1039:
1040: advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
1041:
1042: SAFREE (sa);
1043: }
1044:
1045: /* PSAP */
1046:
1047: #define PMASK \
1048: "\020\01MANAGEMENT\02RESTORATION"
1049:
1050: #define dotoken(requires,shift,bit,type) \
1051: { \
1052: if (srequirements & requires) \
1053: switch (ps -> ps_settings & (ST_MASK << shift)) { \
1054: case ST_CALL_VALUE << shift: \
1055: advise (LLOG_DEBUG, NULLCP, "%s token: choice", type); \
1056: ps -> ps_settings &= ~(ST_MASK << shift); \
1057: ps -> ps_settings |= ST_INIT_VALUE << shift; \
1058: break; \
1059: \
1060: case ST_INIT_VALUE: \
1061: advise (LLOG_DEBUG, NULLCP, "%s token: initiator", type); \
1062: break; \
1063: \
1064: case ST_RESP_VALUE: \
1065: advise (LLOG_DEBUG, NULLCP, "%s token: responder", type); \
1066: owned |= bit; \
1067: break; \
1068: \
1069: default: \
1070: adios (NULLCP, "%s token: reserved", type); \
1071: break; \
1072: } \
1073: }
1074:
1075:
1076: static int prequirements = 0;
1077: #define srequirements requirements
1078:
1079: static struct PSAPdata ixs;
1080: static struct PSAPdata *ix = &ixs;
1081:
1082: /* */
1083:
1084: static int ps_main (argc, argv)
1085: int argc;
1086: char **argv;
1087: {
1088: int async,
1089: result,
1090: sd;
1091: #ifdef DEBUG
1092: int i;
1093: #endif
1094: register struct dispatch *ds;
1095: register struct isoservent *is;
1096: struct PSAPdata pxs;
1097: register struct PSAPdata *px = &pxs;
1098: struct PSAPindication pis;
1099: register struct PSAPindication *pi = &pis;
1100: register struct PSAPabort *pa = &pi -> pi_abort;
1101: struct AcSAPstart acss;
1102: register struct AcSAPstart *acs = &acss;
1103: register struct PSAPstart *ps = &acs -> acs_start;
1104: register struct PSAPctxlist *pl = &ps -> ps_ctxlist;
1105: struct AcSAPindication acis;
1106: register struct AcSAPindication *aci = &acis;
1107: register struct AcSAPabort *aca = &aci -> aci_abort;
1108:
1109: if (isacs) {
1110: if (AcInit (argc, argv, acs, aci) == NOTOK)
1111: acs_adios (aca, "(Ac)initialization fails");
1112:
1113: advise (LLOG_NOTICE, NULLCP,
1114: "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
1115: acs -> acs_sd, oid2ode (acs -> acs_context),
1116: sprintaei (&acs -> acs_callingtitle),
1117: sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
1118:
1119: advise (LLOG_NOTICE, NULLCP,
1120: "PSAP: <%d, %s, %s, %d, %s,",
1121: ps -> ps_sd,
1122: paddr2str (&ps -> ps_calling, NULLNA),
1123: paddr2str (&ps -> ps_called, NULLNA),
1124: pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
1125: advise (LLOG_NOTICE, NULLCP,
1126: " %s, %d, %d>",
1127: sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
1128: ps -> ps_ssdusize);
1129:
1130: sd = acs -> acs_sd;
1131: }
1132: else {
1133: if (PInit (argc, argv, ps, pi) == NOTOK)
1134: ps_adios (pa, "(P)initialization fails");
1135: advise (LLOG_NOTICE, NULLCP,
1136: "P-CONNECT.INDICATION: <%d, %s, %s, %d, %s,",
1137: ps -> ps_sd,
1138: paddr2str (&ps -> ps_calling, NULLNA),
1139: paddr2str (&ps -> ps_called, NULLNA),
1140: pl -> pc_nctx,
1141: sprintb (ps -> ps_prequirements, PMASK));
1142: advise (LLOG_NOTICE, NULLCP,
1143: " %s, %d, %d>",
1144: sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
1145: ps -> ps_ssdusize);
1146:
1147: sd = ps -> ps_sd;
1148: }
1149: #ifdef DEBUG
1150: if (ps -> ps_ninfo > 0)
1151: advise (LLOG_DEBUG, NULLCP, "greetings: %d elements", ps -> ps_ninfo);
1152:
1153: for (i = 0; i < pl -> pc_nctx; i++)
1154: advise (LLOG_DEBUG, NULLCP, " ctx %d: %d %s 0x%x %d",
1155: i, pl -> pc_ctx[i].pc_id, sprintoid (pl -> pc_ctx[i].pc_asn),
1156: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
1157: if (ps -> ps_defctx)
1158: advise (LLOG_DEBUG, NULLCP, " default: %s %d",
1159: sprintoid (ps -> ps_defctx), ps -> ps_defctxresult);
1160: #endif
1161:
1162: ps -> ps_prequirements &= PR_MANAGEMENT | PR_RESTORATION;
1163: prequirements = ps -> ps_prequirements;
1164: advise (LLOG_DEBUG, NULLCP, "new presentation requirements: %s",
1165: sprintb (ps -> ps_prequirements, PMASK));
1166: ps -> ps_srequirements &= SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
1167: | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
1168: | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
1169: if ((ps -> ps_srequirements & SR_HALFDUPLEX)
1170: && (ps -> ps_srequirements & SR_DUPLEX))
1171: ps -> ps_srequirements &= ~SR_DUPLEX;
1172: srequirements = ps -> ps_srequirements;
1173: advise (LLOG_DEBUG, NULLCP, "new session requirements: %s",
1174: sprintb (ps -> ps_srequirements, RMASK));
1175: dotokens ();
1176: advise (LLOG_DEBUG, NULLCP, "initial tokens: %s", sprintb (owned, TMASK));
1177: if (!(ps -> ps_srequirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)))
1178: ps -> ps_isn = SERIAL_NONE;
1179:
1180: if (isacs) {
1181: struct TSAPaddr *ta = &ps -> ps_called.pa_addr.sa_addr;
1182:
1183: if (is = getisoserventbyselector ("tsap", ta -> ta_selector,
1184: ta -> ta_selectlen))
1185: for (ds = acs_dispatches; ds -> ds_entity; ds++)
1186: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
1187: mymode = ds -> ds_mode;
1188: break;
1189: }
1190: }
1191: else
1192: if (is = getisoserventbyselector ("psap", ps -> ps_called.pa_selector,
1193: ps -> ps_called.pa_selectlen))
1194: for (ds = ps_dispatches; ds -> ds_entity; ds++)
1195: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
1196: mymode = ds -> ds_mode;
1197: break;
1198: }
1199:
1200: async = 0;
1201: for (argv++; *argv; argv++) {
1202: if (strcmp (*argv, "-async") == 0) {
1203: async++;
1204: continue;
1205: }
1206: if (strcmp (*argv, "-sync") == 0) {
1207: async = 0;
1208: continue;
1209: }
1210:
1211: advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
1212: }
1213:
1214: if (isacs) {
1215: switch (mymode) {
1216: case echo:
1217: if (AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL,
1218: NULLOID, NULLAEI, NULLPA, pl,
1219: ps -> ps_defctxresult, ps -> ps_prequirements,
1220: ps -> ps_srequirements, ps -> ps_isn,
1221: ps -> ps_settings, &ps -> ps_connect,
1222: acs -> acs_info, acs -> acs_ninfo, aci) == NOTOK)
1223: acs_adios (aca, "A-ASSOCIATE.RESPONSE (accept)");
1224: break;
1225:
1226: case sink:
1227: if (AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL,
1228: NULLOID, NULLAEI, NULLPA, pl,
1229: ps -> ps_defctxresult, ps -> ps_prequirements,
1230: ps -> ps_srequirements, ps -> ps_isn,
1231: ps -> ps_settings, &ps -> ps_connect,
1232: NULLPEP, 0, aci) == NOTOK)
1233: acs_adios (aca, "A-ASSOCIATE.RESPONSE (accept)");
1234: break;
1235:
1236: default:
1237: if (AcAssocResponse (sd, ACS_PERMANENT, ACS_CONTEXT,
1238: NULLOID, NULLAEI, NULLPA, pl,
1239: ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0,
1240: &ps -> ps_connect, NULLPEP, 0, aci) == NOTOK)
1241: acs_adios (aca, "A-ASSOCIATE.RESPONSE (reject)");
1242: advise (LLOG_NOTICE, NULLCP, "rejected");
1243: exit (1);
1244: }
1245:
1246: ACSFREE (acs);
1247:
1248: {
1249: struct RoSAPindication rois;
1250: register struct RoSAPpreject *rop = &rois.roi_preject;
1251:
1252: if (RoSetService (sd, RoPService, &rois) == NOTOK)
1253: ros_adios (rop, "set RO/PS fails");
1254: }
1255:
1256: do_ros (sd, async);
1257: return;
1258: }
1259: else {
1260: switch (mymode) {
1261: case echo:
1262: if (PConnResponse (sd, PC_ACCEPT, NULLPA,
1263: pl, ps -> ps_defctxresult,
1264: ps -> ps_prequirements, ps -> ps_srequirements,
1265: ps -> ps_isn, ps -> ps_settings, &ps -> ps_connect,
1266: ps -> ps_info, ps -> ps_ninfo, pi) == NOTOK)
1267: ps_adios (pa, "P-CONNECT.RESPONSE (accept)");
1268: break;
1269:
1270: case sink:
1271: if (PConnResponse (sd, PC_ACCEPT, NULLPA,
1272: pl, ps -> ps_defctxresult,
1273: ps -> ps_prequirements, ps -> ps_srequirements,
1274: ps -> ps_isn, ps -> ps_settings, &ps -> ps_connect,
1275: NULLPEP, 0, pi) == NOTOK)
1276: ps_adios (pa, "P-CONNECT.RESPONSE (accept)");
1277: break;
1278:
1279: default:
1280: if (PConnResponse (sd, PC_REJECTED, NULLPA,
1281: pl, ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0,
1282: &ps -> ps_connect, NULLPEP, 0, pi) == NOTOK)
1283: ps_adios (pa, "P-CONNECT.RESPONSE (reject)");
1284: advise (LLOG_NOTICE, NULLCP, "rejected");
1285: exit (1);
1286: }
1287:
1288: PSFREE (ps);
1289: }
1290:
1291: if (async) {
1292: if (PSetIndications (sd, ps_dataindication, ps_tokenindication,
1293: ps_syncindication, ps_actindication, ps_reportindication,
1294: ps_finishindication, ps_abortindication, pi) == NOTOK)
1295: ps_adios (pa, "set ASYNC fails");
1296:
1297: for (;;)
1298: pause ();
1299: }
1300:
1301: for (;;)
1302: switch (result = PReadRequest (sd, px, NOTOK, pi)) {
1303: case NOTOK:
1304: ps_abortindication (sd, pa);
1305:
1306: case OK:
1307: ps_dataindication (sd, px);
1308: break;
1309:
1310: case DONE:
1311: switch (pi -> pi_type) {
1312: case PI_TOKEN:
1313: ps_tokenindication (sd, &pi -> pi_token);
1314: break;
1315:
1316: case PI_SYNC:
1317: ps_syncindication (sd, &pi -> pi_sync);
1318: break;
1319:
1320: case PI_ACTIVITY:
1321: ps_actindication (sd, &pi -> pi_activity);
1322: break;
1323:
1324: case PI_REPORT:
1325: ps_reportindication (sd, &pi -> pi_report);
1326: break;
1327:
1328: case PI_FINISH:
1329: ps_finishindication (sd, &pi -> pi_finish);
1330: break;
1331:
1332: default:
1333: adios (NULLCP, "unknown indication type=0x%x",
1334: pi -> pi_type);
1335: }
1336: break;
1337:
1338: default:
1339: adios (NULLCP, "unknown return from PReadRequest=%d", result);
1340: }
1341: }
1342:
1343: #undef dotoken
1344:
1345: /* */
1346:
1347: static int ps_dataindication (sd, px)
1348: int sd;
1349: register struct PSAPdata *px;
1350: {
1351: struct PSAPindication pis;
1352: register struct PSAPindication *pi = &pis;
1353: register struct PSAPabort *pa = &pi -> pi_abort;
1354:
1355: #ifdef DEBUG
1356: switch (px -> px_type) {
1357: case SX_NORMAL:
1358: advise (LLOG_DEBUG, NULLCP, "normal data, %d elements",
1359: px -> px_ninfo);
1360: break;
1361:
1362: case SX_EXPEDITED:
1363: advise (LLOG_DEBUG, NULLCP, "expedited data, %d elements",
1364: px -> px_ninfo);
1365: break;
1366:
1367: case SX_TYPED:
1368: advise (LLOG_DEBUG, NULLCP, "typed data, %d elements",
1369: px -> px_ninfo);
1370: break;
1371:
1372: case SX_CAPDIND:
1373: advise (LLOG_DEBUG, NULLCP, "capability data, %d elements",
1374: px -> px_ninfo);
1375: break;
1376:
1377: case SX_CAPDCNF:
1378: advise (LLOG_DEBUG, NULLCP, "capability data ack, %d elements",
1379: px -> px_ninfo);
1380:
1381: default:
1382: advise (LLOG_DEBUG, NULLCP,
1383: "unknown data indication type=0x%x, %d elements",
1384: px -> px_type, px -> px_ninfo);
1385: }
1386: #endif
1387:
1388: switch (px -> px_type) {
1389: case SX_NORMAL:
1390: if (mymode == sink)
1391: break;
1392: if (srequirements & SR_HALFDUPLEX) {
1393: if (ix -> px_ninfo) {
1394: if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
1395: ps_adios (pa, "P-U-ABORT.REQUEST");
1396: else
1397: adios (NULLCP, "protocol screw-up");
1398: }
1399: else {
1400: *ix = *px; /* struct copy */
1401: bzero ((char *) px, sizeof *px);
1402: if (!(owned & ST_DAT_TOKEN)
1403: && PPTokenRequest (sd, ST_DAT_TOKEN, NULLPEP,
1404: 0, pi) == NOTOK)
1405: ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
1406: }
1407: }
1408: else
1409: if (PDataRequest (sd, px -> px_info, px -> px_ninfo, pi)
1410: == NOTOK)
1411: ps_adios (pa, "P-DATA.REQUEST");
1412: break;
1413:
1414: case SX_EXPEDITED:
1415: if (mymode == sink)
1416: break;
1417: if (PExpdRequest (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
1418: ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
1419: break;
1420:
1421: case SX_TYPED:
1422: if (mymode == sink)
1423: break;
1424: if (PTypedRequest (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
1425: ps_adios (pa, "P-TYPED-DATA.REQUEST");
1426: break;
1427:
1428: case SX_CAPDIND:
1429: if (PCapdResponse (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
1430: ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
1431: break;
1432:
1433: case SX_CAPDCNF:
1434: adios (NULLCP, "got capability data response");
1435:
1436: default:
1437: adios (NULLCP, "unknown data indication type=0x%x", px -> px_type);
1438: }
1439:
1440: PXFREE (px);
1441: }
1442:
1443: /* */
1444:
1445: static int ps_tokenindication (sd, pt)
1446: int sd;
1447: register struct PSAPtoken *pt;
1448: {
1449: struct PSAPindication pis;
1450: register struct PSAPindication *pi = &pis;
1451: register struct PSAPabort *pa = &pi -> pi_abort;
1452:
1453: #ifdef DEBUG
1454: advise (LLOG_DEBUG, NULLCP, "%s tokens: %s, %d elements",
1455: pt -> pt_type == ST_PLEASE ? "please"
1456: : pt -> pt_type == ST_GIVE ? "give" : "control",
1457: sprintb ((int) pt -> pt_tokens, TMASK),
1458: pt -> pt_ninfo);
1459: #endif
1460:
1461: switch (pt -> pt_type) {
1462: case ST_GIVE:
1463: case ST_CONTROL:
1464: owned = pt -> pt_owned;
1465: break;
1466:
1467: case ST_PLEASE:
1468: break;
1469:
1470: default:
1471: adios (NULLCP, "unknown token indication type=0x%x",
1472: pt -> pt_type);
1473: }
1474:
1475: if ((owned & ST_DAT_TOKEN) && ix -> px_ninfo)
1476: if (PDataRequest (sd, ix -> px_info, ix -> px_ninfo, pi) == NOTOK)
1477: ps_adios (pa, "P-DATA.REQUEST");
1478: else {
1479: PXFREE (ix);
1480: bzero ((char *) ix, sizeof *ix);
1481: }
1482:
1483: switch (pt -> pt_type) {
1484: case ST_GIVE:
1485: break;
1486:
1487: default:
1488: if (PGTokenRequest (sd, (int) pt -> pt_tokens, pi) == NOTOK)
1489: ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
1490: else
1491: owned &= ~pt -> pt_tokens;
1492: break;
1493: }
1494:
1495: PTFREE (pt);
1496: }
1497:
1498: /* */
1499:
1500: static int ps_syncindication (sd, pn)
1501: int sd;
1502: register struct PSAPsync *pn;
1503: {
1504: struct PSAPindication pis;
1505: register struct PSAPindication *pi = &pis;
1506: register struct PSAPabort *pa = &pi -> pi_abort;
1507:
1508: #ifdef DEBUG
1509: switch (pn -> pn_type) {
1510: case SN_MAJORIND:
1511: advise (LLOG_DEBUG, NULLCP, "majorsync indication %d",
1512: pn -> pn_ssn);
1513: break;
1514:
1515: case SN_MAJORCNF:
1516: advise (LLOG_DEBUG, NULLCP, "majorsync confirmation %d",
1517: pn -> pn_ssn);
1518: break;
1519:
1520: case SN_MINORIND:
1521: advise (LLOG_DEBUG, NULLCP, "minorsync indication %d%s",
1522: pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
1523: ? " (wants confirmation)" : NULLCP);
1524: break;
1525:
1526: case SN_MINORCNF:
1527: advise (LLOG_DEBUG, NULLCP, "minorsync confirmation %d",
1528: pn -> pn_ssn);
1529: break;
1530:
1531: case SN_RESETIND:
1532: advise (LLOG_DEBUG, NULLCP, "resync indication type=%d %d",
1533: pn -> pn_options, pn -> pn_ssn);
1534: break;
1535:
1536: case SN_RESETCNF:
1537: advise (LLOG_DEBUG, NULLCP, "resync confirmation %d",
1538: pn -> pn_ssn);
1539: break;
1540:
1541: default:
1542: advise (LLOG_DEBUG, NULLCP, "unknown sync indication=0x%x, ssn=%d",
1543: pn -> pn_type, pn -> pn_ssn);
1544: break;
1545: }
1546: advise (LLOG_DEBUG, NULLCP, "%d elements", pn -> pn_ninfo);
1547: #endif
1548:
1549: switch (pn -> pn_type) {
1550: case SN_MAJORIND:
1551: if (PMajSyncResponse (sd,
1552: mymode == echo ? pn -> pn_info : NULLPEP,
1553: mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
1554: ps_adios (pa, "P-MAJOR-SYNC.RESPONSE");
1555: break;
1556:
1557: case SN_MAJORCNF:
1558: adios (NULLCP, "got majorsync confirmation");
1559:
1560: case SN_MINORIND:
1561: if (pn -> pn_options == SYNC_CONFIRM)
1562: if (PMinSyncResponse (sd, pn -> pn_ssn,
1563: mymode == echo ? pn -> pn_info : NULLPEP,
1564: mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
1565: ps_adios (pa, "P-MINOR-SYNC.RESPONSE");
1566: break;
1567:
1568: case SN_MINORCNF:
1569: adios (NULLCP, "got minorsync confirmation");
1570:
1571: case SN_RESETIND:
1572: #define dotoken(requires,shift,bit,type) \
1573: { \
1574: if (srequirements & requires) \
1575: switch (pn -> pn_settings & (ST_MASK << shift)) { \
1576: case ST_CALL_VALUE << shift: \
1577: pn -> pn_settings &= ~(ST_MASK << shift); \
1578: pn -> pn_settings |= ST_RESP_VALUE << shift; \
1579: case ST_RESP_VALUE << shift: \
1580: owned |= bit; \
1581: break; \
1582: \
1583: case ST_INIT_VALUE << shift: \
1584: owned &= ~bit; \
1585: break; \
1586: \
1587: default: \
1588: adios (NULLCP, "%s token: reserved", type); \
1589: break; \
1590: } \
1591: }
1592: dotokens ();
1593: #undef dotoken
1594: if (PReSyncRequest (sd, SYNC_ABANDON, SERIAL_NONE,
1595: pn -> pn_settings,
1596: mymode == echo ? pn -> pn_info : NULLPEP,
1597: mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
1598: ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
1599: break;
1600:
1601: case SN_RESETCNF:
1602: break;
1603:
1604: default:
1605: adios (NULLCP, "unknown sync indication type=0x%x", pn -> pn_type);
1606: }
1607:
1608: PNFREE (pn);
1609: }
1610:
1611: /* */
1612:
1613: static int ps_actindication (sd, pv)
1614: int sd;
1615: register struct PSAPactivity *pv;
1616: {
1617: struct PSAPindication pis;
1618: register struct PSAPindication *pi = &pis;
1619: register struct PSAPabort *pa = &pi -> pi_abort;
1620:
1621: #ifdef DEBUG
1622: switch (pv -> pv_type) {
1623: case SV_START:
1624: advise (LLOG_DEBUG, NULLCP, "activity start indication: %*.*s",
1625: pv -> pv_id.sd_len, pv -> pv_id.sd_len,
1626: pv -> pv_id.sd_data);
1627: break;
1628:
1629: case SV_RESUME:
1630: advise (LLOG_DEBUG, NULLCP,
1631: "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
1632: pv -> pv_id.sd_len, pv -> pv_id.sd_len,
1633: pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
1634: pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
1635: sprintref (&pv -> pv_connect), pv -> pv_ssn);
1636: break;
1637:
1638: case SV_INTRIND:
1639: advise (LLOG_DEBUG, NULLCP, "activity interrupt indication %d",
1640: pv -> pv_reason);
1641: break;
1642:
1643: case SV_INTRCNF:
1644: advise (LLOG_DEBUG, NULLCP, "activity interrupt confirmation");
1645: break;
1646:
1647: case SV_DISCIND:
1648: advise (LLOG_DEBUG, NULLCP, "activity discard indication %d",
1649: pv -> pv_reason);
1650: break;
1651:
1652: case SV_DISCCNF:
1653: advise (LLOG_DEBUG, NULLCP, "activity discard confirmation");
1654: break;
1655:
1656: case SV_ENDIND:
1657: advise (LLOG_DEBUG, NULLCP, "activity end indication %d",
1658: pv -> pv_ssn);
1659: break;
1660:
1661: case SV_ENDCNF:
1662: advise (LLOG_DEBUG, NULLCP, "activity end confirmation");
1663: break;
1664:
1665: default:
1666: advise (LLOG_DEBUG, NULLCP, "unknown activity indication=0x%x",
1667: pv -> pv_type);
1668: break;
1669: }
1670: advise (LLOG_DEBUG, NULLCP, "%d elements", pv -> pv_ninfo);
1671: #endif
1672:
1673: switch (pv -> pv_type) {
1674: case SV_START:
1675: case SV_RESUME:
1676: break;
1677:
1678: case SV_INTRIND:
1679: if (PActIntrResponse (sd, pi) == NOTOK)
1680: ps_adios (pa, "P-ACTIVITY-INTERRUPT.RESPONSE");
1681: owned = 0;
1682: break;
1683:
1684: case SV_INTRCNF:
1685: adios (NULLCP, "got activity interrupt confirmation");
1686:
1687: case SV_DISCIND:
1688: if (PActDiscResponse (sd, pi) == NOTOK)
1689: ps_adios (pa, "P-ACTIVITY-DISCARD.RESPONSE");
1690: owned = 0;
1691: break;
1692:
1693: case SV_DISCCNF:
1694: adios (NULLCP, "got activity discard confirmation");
1695:
1696: case SV_ENDIND:
1697: if (PActEndResponse (sd, mymode == echo ? pv -> pv_info : NULLPEP,
1698: mymode == echo ? pv -> pv_ninfo : 0, pi) == NOTOK)
1699: ps_adios (pa, "P-ACTIVITY-END.RESPONSE");
1700: break;
1701:
1702: case SV_ENDCNF:
1703: adios (NULLCP, "got activity end confirmation");
1704:
1705: default:
1706: adios (NULLCP, "unknown activity indication=0x%x", pv -> pv_type);
1707: }
1708:
1709: PVFREE (pv);
1710: }
1711:
1712: /* */
1713:
1714: static int ps_reportindication (sd, pp)
1715: int sd;
1716: register struct PSAPreport *pp;
1717: {
1718: struct PSAPindication pis;
1719: register struct PSAPindication *pi = &pis;
1720: register struct PSAPabort *pa = &pi -> pi_abort;
1721:
1722: #ifdef DEBUG
1723: advise (LLOG_NOTICE, NULLCP, "%s report %d, %d elements",
1724: pp -> pp_peer ? "user" : "provider", pp -> pp_reason,
1725: pp -> pp_ninfo);
1726: #endif
1727:
1728: if (srequirements & SR_DAT_EXISTS) {
1729: if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
1730: ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
1731: else
1732: owned &= ~ST_DAT_TOKEN;
1733: #ifdef DEBUG
1734: advise (LLOG_DEBUG, NULLCP, "cleared");
1735: #endif
1736: }
1737: else
1738: if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
1739: ps_adios (pa, "P-U-ABORT.REQUEST");
1740: else
1741: adios (NULLCP, "aborted");
1742:
1743: PPFREE (pp);
1744: }
1745:
1746: /* */
1747:
1748: static int ps_finishindication (sd, pf)
1749: int sd;
1750: register struct PSAPfinish *pf;
1751: {
1752: struct PSAPindication pis;
1753: register struct PSAPindication *pi = &pis;
1754: register struct PSAPabort *pa = &pi -> pi_abort;
1755: struct AcSAPindication acis;
1756: register struct AcSAPabort *aca = &acis.aci_abort;
1757: register struct AcSAPfinish *acf = &acis.aci_finish;
1758:
1759: if (isacs) {
1760: if (AcFINISHser (sd, pf, &acis) == NOTOK)
1761: acs_adios (aca, "AcFINISHser");
1762: ros_finish (sd, acf);
1763: return;
1764: }
1765:
1766: advise (LLOG_NOTICE, NULLCP, "P-RELEASE.INDICATION: %d elements",
1767: pf -> pf_ninfo);
1768:
1769: if (PRelResponse (sd, SC_ACCEPT, mymode == echo ? pf -> pf_info : NULLPEP,
1770: mymode == echo ? pf -> pf_ninfo : 0, pi) == NOTOK)
1771: ps_adios (pa, "P-RELEASE.RESPONSE");
1772:
1773: PFFREE (pf);
1774:
1775: exit (0);
1776: }
1777:
1778:
1779: /* ARGSUSED */
1780:
1781: static int ps_abortindication (sd, pa)
1782: int sd;
1783: register struct PSAPabort *pa;
1784: {
1785: struct AcSAPindication acis;
1786: register struct AcSAPindication *aci = &acis;
1787: register struct AcSAPabort *aca = &aci -> aci_abort;
1788:
1789: if (isacs) {
1790: if (AcABORTser (sd, pa, aci) == NOTOK)
1791: acs_adios (aca, "AcABORTser");
1792: advise (LLOG_NOTICE, NULLCP, "A-%sABORT.INDICATION: [%s] %d elements",
1793: aca -> aca_source != ACA_USER ? "P-" : "",
1794: AcErrString (aca -> aca_reason), aca -> aca_ninfo);
1795:
1796: ACAFREE (aca);
1797:
1798: exit (1);
1799: }
1800:
1801: if (!pa -> pa_peer)
1802: ps_adios (pa, "P-P-ABORT.INDICATION");
1803:
1804: advise (LLOG_NOTICE, NULLCP, "P-U-ABORT.INDICATION: %d elements",
1805: pa -> pa_ninfo);
1806: PAFREE (pa);
1807:
1808: exit (1);
1809: }
1810:
1811: /* */
1812:
1813: static void ps_adios (pa, event)
1814: register struct PSAPabort *pa;
1815: char *event;
1816: {
1817: ps_advise (pa, event);
1818:
1819: _exit (1);
1820: }
1821:
1822:
1823: static void ps_advise (pa, event)
1824: register struct PSAPabort *pa;
1825: char *event;
1826: {
1827: char buffer[BUFSIZ];
1828:
1829: if (pa -> pa_cc > 0)
1830: (void) sprintf (buffer, "[%s] %*.*s",
1831: PErrString (pa -> pa_reason),
1832: pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
1833: else
1834: (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
1835:
1836: advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
1837: }
1838:
1839: /* AcSAP */
1840:
1841: static void acs_adios (aca, event)
1842: register struct AcSAPabort *aca;
1843: char *event;
1844: {
1845: acs_advise (aca, event);
1846:
1847: _exit (1);
1848: }
1849:
1850:
1851: static void acs_advise (aca, event)
1852: register struct AcSAPabort *aca;
1853: char *event;
1854: {
1855: char buffer[BUFSIZ];
1856:
1857: if (aca -> aca_cc > 0)
1858: (void) sprintf (buffer, "[%s] %*.*s",
1859: AcErrString (aca -> aca_reason),
1860: aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
1861: else
1862: (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
1863:
1864: advise (LLOG_NOTICE, NULLCP, "%s: %s (source %d)", event, buffer,
1865: aca -> aca_source);
1866: }
1867:
1868: /* RtSAP */
1869:
1870: static int rts_main (argc, argv)
1871: int argc;
1872: char **argv;
1873: {
1874: int async,
1875: result,
1876: ros,
1877: sd;
1878: #ifdef DEBUG
1879: int i;
1880: #endif
1881: struct dispatch *ds;
1882: struct isoservent *is;
1883: struct RtSAPstart rtss;
1884: register struct RtSAPstart *rts = &rtss;
1885: struct RtSAPindication rtis;
1886: register struct RtSAPindication *rti = &rtis;
1887: register struct RtSAPabort *rta = &rti -> rti_abort;
1888: register struct AcSAPstart *acs = &rts -> rts_start;
1889: register struct PSAPstart *ps = &acs -> acs_start;
1890: register struct PSAPctxlist *pl = &ps -> ps_ctxlist;
1891:
1892: if (isacs) {
1893: if (RtInit (argc, argv, rts, rti) == NOTOK)
1894: rts_adios (rta, "(Rt)initialization fails");
1895: advise (LLOG_NOTICE, NULLCP, "RT-OPEN.INDICATION: <%d, %s, %s, 0x%x>",
1896: rts -> rts_sd,
1897: rts -> rts_mode == RTS_TWA ? "twa" : "mono",
1898: rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
1899: rts -> rts_data);
1900:
1901: advise (LLOG_NOTICE, NULLCP, "ACSE: <%d, %s, %s, %s, %d>",
1902: acs -> acs_sd, oid2ode (acs -> acs_context),
1903: sprintaei (&acs -> acs_callingtitle),
1904: sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
1905:
1906: advise (LLOG_NOTICE, NULLCP,
1907: "PSAP: <%d, %s, %s, %d, %s,",
1908: ps -> ps_sd,
1909: paddr2str (&ps -> ps_calling, NULLNA),
1910: paddr2str (&ps -> ps_called, NULLNA),
1911: pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
1912: advise (LLOG_NOTICE, NULLCP,
1913: " %s, %d, %d>",
1914: sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
1915: ps -> ps_ssdusize);
1916:
1917: #ifdef DEBUG
1918: {
1919: if (ps -> ps_ninfo > 0)
1920: advise (LLOG_DEBUG, NULLCP, "greetings: %d elements",
1921: ps -> ps_ninfo);
1922:
1923: for (i = 0; i < pl -> pc_nctx; i++)
1924: advise (LLOG_DEBUG, NULLCP, " ctx %d: %d %s 0x%x %d",
1925: i, pl -> pc_ctx[i].pc_id,
1926: sprintoid (pl -> pc_ctx[i].pc_asn),
1927: pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
1928: if (ps -> ps_defctx)
1929: advise (LLOG_DEBUG, NULLCP, " default: %s %d",
1930: sprintoid (ps -> ps_defctx), ps -> ps_defctxresult);
1931: }
1932: #endif
1933:
1934: }
1935: else {
1936: if (RtBInit (argc, argv, rts, rti) == NOTOK)
1937: rts_adios (rta, "(RtB)initialization fails");
1938: advise (LLOG_NOTICE, NULLCP,
1939: "RT-BEGIN.INDICATION: <%d, %s, %s, <%d, %s>, 0x%x>",
1940: rts -> rts_sd, rts -> rts_mode == RTS_TWA ? "twa" :"monologue",
1941: rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
1942: ntohs (rts -> rts_port),
1943: saddr2str (&rts -> rts_initiator.rta_addr),
1944: rts -> rts_data);
1945: }
1946:
1947: if (rts -> rts_data) {
1948: if ((result = prim2num (rts -> rts_data)) == NOTOK
1949: && rts -> rts_data -> pe_errno != PE_ERR_NONE)
1950: adios (NULLCP, "error decoding hello: %s",
1951: pe_error (rts -> rts_data -> pe_errno));
1952:
1953: advise (LLOG_DEBUG, NULLCP, "received greetings of %d", result);
1954:
1955: pe_free (rts -> rts_data);
1956: if ((rts -> rts_data = int2prim (result = getpid ())) == NULLPE)
1957: adios (NULLCP, "unable to allocate hello");
1958: }
1959:
1960: sd = rts -> rts_sd;
1961:
1962: if (isacs) {
1963: struct TSAPaddr *ta = &ps -> ps_called.pa_addr.sa_addr;
1964:
1965: if (is = getisoserventbyselector ("tsap", ta -> ta_selector,
1966: ta -> ta_selectlen))
1967: for (ds = rtse_dispatches; ds -> ds_entity; ds++)
1968: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
1969: mymode = ds -> ds_mode;
1970: break;
1971: }
1972: }
1973: else
1974: if (is = getisoserventbyport ("rtsap", rts -> rts_port))
1975: for (ds = rts_dispatches; ds -> ds_entity; ds++)
1976: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
1977: mymode = ds -> ds_mode;
1978: break;
1979: }
1980:
1981: async = 0;
1982: ros = !isacs && strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0;
1983: for (argv++; *argv; argv++) {
1984: if (strcmp (*argv, "-async") == 0) {
1985: async++;
1986: continue;
1987: }
1988: if (strcmp (*argv, "-sync") == 0) {
1989: async = 0;
1990: continue;
1991: }
1992: if (strcmp (*argv, "-rtse") == 0)
1993: continue;
1994: if (strcmp (*argv, "-rose") == 0) {
1995: ros++;
1996: continue;
1997: }
1998:
1999: advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
2000: }
2001:
2002: if (isacs) {
2003: switch (mymode) {
2004: case echo:
2005: if (rts -> rts_mode == RTS_TWA)
2006: goto rtse_accept;
2007: rtse_reject: ;
2008: if (RtOpenResponse (sd, ACS_USER_NOREASON, NULLOID, NULLAEI,
2009: NULLPA, NULLPC, ps -> ps_defctxresult, NULLPE, rti)
2010: == NOTOK)
2011: rts_adios (rta, "RT-OPEN.RESPONSE (reject)");
2012: advise (LLOG_NOTICE, NULLCP, "rejected");
2013: exit (1);
2014:
2015: case sink:
2016: if (rts -> rts_mode != RTS_TWA
2017: && rts -> rts_turn != RTS_INITIATOR)
2018: goto rtse_reject;
2019: rtse_accept:
2020: if (RtOpenResponse (sd, ACS_ACCEPT, NULLOID, NULLAEI,
2021: NULLPA, pl, ps -> ps_defctxresult,
2022: rts -> rts_data, rti) == NOTOK)
2023: rts_adios (rta, "RT-OPEN.RESPONSE (accept)");
2024: advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
2025: break;
2026:
2027: default:
2028: goto rtse_reject;
2029: }
2030: }
2031: else {
2032: switch (mymode) {
2033: case echo:
2034: if (rts -> rts_mode == RTS_TWA)
2035: goto accept;
2036: reject: ;
2037: if (RtBeginResponse (sd, RTS_MODE, NULLPE, rti) == NOTOK)
2038: rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
2039: advise (LLOG_NOTICE, NULLCP, "rejected");
2040: exit (1);
2041:
2042: case sink:
2043: if (rts -> rts_mode != RTS_TWA
2044: && rts -> rts_turn != RTS_INITIATOR)
2045: goto reject;
2046: accept: ;
2047: if (RtBeginResponse (sd, RTS_ACCEPT, rts -> rts_data, rti)
2048: == NOTOK)
2049: rts_adios (rta, "RT-BEGIN.RESPONSE (accept)");
2050: advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
2051: break;
2052:
2053: default:
2054: if (RtBeginResponse (sd, RTS_VALIDATE, NULLPE, rti) == NOTOK)
2055: rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
2056: advise (LLOG_NOTICE, NULLCP, "rejected");
2057: exit (1);
2058: }
2059: }
2060:
2061: RTSFREE (rts);
2062:
2063: if (ros) {
2064: struct RoSAPindication rois;
2065: register struct RoSAPpreject *rop = &rois.roi_preject;
2066:
2067: if (RoSetService (sd, RoRtService, &rois) == NOTOK)
2068: ros_adios (rop, "set RO/RT fails");
2069:
2070: do_ros (sd, async);
2071: return;
2072: }
2073:
2074: if (async) {
2075: if (RtSetIndications (sd, rts_indication, rti) == NOTOK)
2076: rts_adios (rta, "set ASYNC fails");
2077:
2078: for (;;)
2079: pause ();
2080: }
2081:
2082: for (;;)
2083: switch (result = RtWaitRequest (sd, NOTOK, rti)) {
2084: case NOTOK:
2085: case OK:
2086: case DONE:
2087: rts_indication (sd, rti);
2088: break;
2089:
2090: default:
2091: adios (NULLCP, "unknown return from RtWaitRequest=%d", result);
2092: }
2093: }
2094:
2095: /* */
2096:
2097: static int rts_indication (sd, rti)
2098: int sd;
2099: register struct RtSAPindication *rti;
2100: {
2101: switch (rti -> rti_type) {
2102: case RTI_TURN:
2103: rts_turn (sd, &rti -> rti_turn);
2104: break;
2105:
2106: case RTI_TRANSFER:
2107: rts_transfer (sd, &rti -> rti_transfer);
2108: break;
2109:
2110: case RTI_ABORT:
2111: rts_abort (sd, &rti -> rti_abort);
2112: break;
2113:
2114: case RTI_CLOSE:
2115: rts_close (sd, &rti -> rti_close);
2116: break;
2117:
2118: case RTI_FINISH:
2119: rts_finish (sd, &rti -> rti_finish);
2120: break;
2121:
2122: default:
2123: adios (NULLCP, "unknown indication type=%d", rti -> rti_type);
2124: }
2125: }
2126:
2127: /* */
2128:
2129: static int rts_turn (sd, rtu)
2130: int sd;
2131: register struct RtSAPturn *rtu;
2132: {
2133: struct RtSAPindication rtis;
2134: register struct RtSAPindication *rti = &rtis;
2135: register struct RtSAPabort *rta = &rti -> rti_abort;
2136:
2137: if (rtu -> rtu_please) {
2138: if (RtGTurnRequest (sd, rti) == NOTOK)
2139: rts_adios (rta, "RT-TURN-GIVE.REQUEST");
2140: }
2141: else
2142: if (apdupe) {
2143: if (RtTransferRequest (sd, apdupe, NOTOK, rti) == NOTOK)
2144: rts_adios (rta, "RT-TRANSFER.REQUEST");
2145: pe_free (apdupe);
2146: apdupe = NULLPE;
2147: }
2148: }
2149:
2150: /* */
2151:
2152: static int rts_transfer (sd, rtt)
2153: int sd;
2154: register struct RtSAPtransfer *rtt;
2155: {
2156: struct RtSAPindication rtis;
2157: register struct RtSAPindication *rti = &rtis;
2158: register struct RtSAPabort *rta = &rti -> rti_abort;
2159: static int priority = 1;
2160:
2161: if (mymode == echo) {
2162: if (apdupe)
2163: adios (NULLCP, "protocol screw-up");
2164: if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
2165: rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
2166: apdupe = rtt -> rtt_data;
2167: }
2168: else
2169: RTTFREE (rtt);
2170: }
2171:
2172: /* */
2173:
2174: /* ARGSUSED */
2175:
2176: static int rts_abort (sd, rta)
2177: int sd;
2178: register struct RtSAPabort *rta;
2179: {
2180: if (rta -> rta_peer)
2181: rts_adios (rta, "RT-U-ABORT.INDICATION");
2182:
2183: if (RTS_FATAL (rta -> rta_reason))
2184: rts_adios (rta, "RT-P-ABORT.INDICATION");
2185: rts_advise (rta, "RT-P-ABORT.INDICATION");
2186: }
2187:
2188: /* */
2189:
2190: /* ARGSUSED */
2191:
2192: static int rts_close (sd, rtc)
2193: int sd;
2194: struct RtSAPclose *rtc;
2195: {
2196: struct RtSAPindication rtis;
2197: register struct RtSAPindication *rti = &rtis;
2198: register struct RtSAPabort *rta = &rti -> rti_abort;
2199:
2200: advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
2201:
2202: if (RtEndResponse (sd, rti) == NOTOK)
2203: rts_adios (rta, "RT-END.RESPONSE");
2204:
2205: exit (0);
2206: }
2207:
2208: /* */
2209:
2210: static int rts_finish (sd, acf)
2211: int sd;
2212: register struct AcSAPfinish *acf;
2213: {
2214: struct RtSAPindication rtis;
2215: register struct RtSAPindication *rti = &rtis;
2216: register struct RtSAPabort *rta = &rti -> rti_abort;
2217:
2218: advise (LLOG_NOTICE, NULLCP, "RT-CLOSE.INDICATION: %d, %d elements",
2219: acf -> acf_reason, acf -> acf_ninfo);
2220:
2221: if (RtCloseResponse (sd, ACR_NORMAL, mymode == echo
2222: ? acf -> acf_info[0] : NULLPE, rti) == NOTOK)
2223: rts_adios (rta, "RT-CLOSE.RESPONSE");
2224:
2225: ACFFREE (acf);
2226:
2227: exit (0);
2228: }
2229:
2230: /* */
2231:
2232: static void rts_adios (rta, event)
2233: register struct RtSAPabort *rta;
2234: char *event;
2235: {
2236: rts_advise (rta, event);
2237:
2238: _exit (1);
2239: }
2240:
2241:
2242: static void rts_advise (rta, event)
2243: register struct RtSAPabort *rta;
2244: char *event;
2245: {
2246: char buffer[BUFSIZ];
2247:
2248: if (rta -> rta_cc > 0)
2249: (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason),
2250: rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
2251: else
2252: (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason));
2253:
2254: advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
2255: }
2256:
2257: /* RoSAP */
2258:
2259: static int ros_main (argc, argv)
2260: int argc;
2261: char **argv;
2262: {
2263: int async,
2264: result,
2265: sd;
2266: struct dispatch *ds;
2267: struct isoservent *is;
2268: struct RoSAPstart ross;
2269: register struct RoSAPstart *ros = &ross;
2270: struct RoSAPindication rois;
2271: register struct RoSAPindication *roi = &rois;
2272: register struct RoSAPpreject *rop = &roi -> roi_preject;
2273:
2274: if (RoInit (argc, argv, ros, roi) == NOTOK)
2275: ros_adios (rop, "(Ro)initialization fails");
2276: advise (LLOG_NOTICE, NULLCP, "RO-BEGIN.INDICATION: <%d, <%d, %s>, 0x%x>",
2277: ros -> ros_sd,
2278: ntohs (ros -> ros_port),
2279: saddr2str (&ros -> ros_initiator.roa_addr),
2280: ros -> ros_data);
2281: if (ros -> ros_data) {
2282: if ((result = prim2num (ros -> ros_data)) == NOTOK
2283: && ros -> ros_data -> pe_errno != PE_ERR_NONE)
2284: adios (NULLCP, "error decoding hello: %s",
2285: pe_error (ros -> ros_data -> pe_errno));
2286:
2287: advise (LLOG_DEBUG, NULLCP, "received greetings of %d", result);
2288:
2289: pe_free (ros -> ros_data);
2290: if ((ros -> ros_data = int2prim (result = getpid ())) == NULLPE)
2291: adios (NULLCP, "unable to allocate hello");
2292: }
2293:
2294: sd = ros -> ros_sd;
2295:
2296: if (is = getisoserventbyport ("rosap", ros -> ros_port))
2297: for (ds = ros_dispatches; ds -> ds_entity; ds++)
2298: if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
2299: mymode = ds -> ds_mode;
2300: break;
2301: }
2302:
2303: async = 0;
2304: for (argv++; *argv; argv++) {
2305: if (strcmp (*argv, "-async") == 0) {
2306: async++;
2307: continue;
2308: }
2309: if (strcmp (*argv, "-sync") == 0) {
2310: async = 0;
2311: continue;
2312: }
2313:
2314: advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
2315: }
2316:
2317: switch (mymode) {
2318: case echo:
2319: case sink:
2320: if (RoBeginResponse (sd, ROS_ACCEPT, ros -> ros_data, roi)
2321: == NOTOK)
2322: ros_adios (rop, "RO-BEGIN.RESPONSE (accept)");
2323: advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
2324: break;
2325:
2326: default:
2327: if (RoBeginResponse (sd, ROS_VALIDATE, NULLPE, roi) == NOTOK)
2328: ros_adios (rop, "RO-BEGIN.RESPONSE (reject)");
2329: advise (LLOG_NOTICE, NULLCP, "rejected");
2330: exit (1);
2331: }
2332:
2333: ROSFREE (ros);
2334:
2335: do_ros (sd, async);
2336: }
2337:
2338: /* */
2339:
2340: static int do_ros (sd, async)
2341: int sd,
2342: async;
2343: {
2344: int result;
2345: struct RoSAPindication rois;
2346: register struct RoSAPindication *roi = &rois;
2347: register struct RoSAPpreject *rop = &roi -> roi_preject;
2348:
2349: if ((nullpe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
2350: == NULLPE)
2351: adios (NULLCP, "unable to allocate NULL PE");
2352:
2353: if (async) {
2354: if (RoSetIndications (sd, ros_indication, roi) == NOTOK)
2355: ros_adios (rop, "set ASYNC fails");
2356:
2357: for (;;)
2358: pause ();
2359: }
2360:
2361: for (;;)
2362: switch (result = RoWaitRequest (sd, NOTOK, roi)) {
2363: case NOTOK:
2364: case OK:
2365: case DONE:
2366: ros_indication (sd, roi);
2367: break;
2368:
2369: default:
2370: adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
2371: }
2372: }
2373:
2374: /* */
2375:
2376: static int ros_indication (sd, roi)
2377: int sd;
2378: register struct RoSAPindication *roi;
2379: {
2380: switch (roi -> roi_type) {
2381: case ROI_INVOKE:
2382: ros_invoke (sd, &roi -> roi_invoke);
2383: break;
2384:
2385: case ROI_RESULT:
2386: ros_result (sd, &roi -> roi_result);
2387: break;
2388:
2389: case ROI_ERROR:
2390: ros_error (sd, &roi -> roi_error);
2391: break;
2392:
2393: case ROI_UREJECT:
2394: ros_ureject (sd, &roi -> roi_ureject);
2395: break;
2396:
2397: case ROI_PREJECT:
2398: ros_preject (sd, &roi -> roi_preject);
2399: break;
2400:
2401: case ROI_END:
2402: ros_end (sd, &roi -> roi_end);
2403: break;
2404:
2405: case ROI_FINISH:
2406: ros_finish (sd, &roi -> roi_finish);
2407: break;
2408:
2409: default:
2410: adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
2411: }
2412: }
2413:
2414: /* */
2415:
2416: static int ros_invoke (sd, rox)
2417: int sd;
2418: register struct RoSAPinvoke *rox;
2419: {
2420: struct RoSAPindication rois;
2421: register struct RoSAPindication *roi = &rois;
2422: register struct RoSAPpreject *rop = &roi -> roi_preject;
2423: static int ff = 0;
2424:
2425: if (ff++ & 0x01) {
2426: if (RoErrorRequest (sd, rox -> rox_id, ff,
2427: mymode == echo ? rox -> rox_args : nullpe, ROS_NOPRIO,
2428: roi) == NOTOK)
2429: ros_adios (rop, "RO-ERROR.REQUEST");
2430: }
2431: else {
2432: if (RoResultRequest (sd, rox -> rox_id, rox -> rox_op,
2433: mymode == echo ? rox -> rox_args : nullpe, ROS_NOPRIO,
2434: roi) == NOTOK)
2435: ros_adios (rop, "RO-RESULT.REQUEST");
2436: }
2437:
2438: ROXFREE (rox);
2439: }
2440:
2441: /* */
2442:
2443: static int ros_result (sd, ror)
2444: int sd;
2445: register struct RoSAPresult *ror;
2446: {
2447: struct RoSAPindication rois;
2448: register struct RoSAPindication *roi = &rois;
2449: register struct RoSAPpreject *rop = &roi -> roi_preject;
2450:
2451: if (RoURejectRequest (sd, &ror -> ror_id, ROS_RRP_UNRECOG, ROS_NOPRIO, roi)
2452: == NOTOK)
2453: ros_adios (rop, "RO-REJECT-U.REQUEST");
2454:
2455: RORFREE (ror);
2456: }
2457:
2458: /* */
2459:
2460: static int ros_error (sd, roe)
2461: int sd;
2462: register struct RoSAPerror *roe;
2463: {
2464: struct RoSAPindication rois;
2465: register struct RoSAPindication *roi = &rois;
2466: register struct RoSAPpreject *rop = &roi -> roi_preject;
2467:
2468: if (RoURejectRequest (sd, &roe -> roe_id, ROS_REP_UNRECOG, ROS_NOPRIO, roi)
2469: == NOTOK)
2470: ros_adios (rop, "RO-REJECT-U.REQUEST");
2471:
2472: ROEFREE (roe);
2473: }
2474:
2475: /* */
2476:
2477: /* ARGSUSED */
2478:
2479: static int ros_ureject (sd, rou)
2480: int sd;
2481: register struct RoSAPureject *rou;
2482: {
2483: if (rou -> rou_noid)
2484: advise (LLOG_NOTICE, NULLCP, "RO-REJECT-U.INDICATION: %s",
2485: RoErrString (rou -> rou_reason));
2486: else
2487: advise (LLOG_NOTICE, NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
2488: RoErrString (rou -> rou_reason), rou -> rou_id);
2489: }
2490:
2491: /* */
2492:
2493: /* ARGSUSED */
2494:
2495: static int ros_preject (sd, rop)
2496: int sd;
2497: register struct RoSAPpreject *rop;
2498: {
2499: if (ROS_FATAL (rop -> rop_reason))
2500: ros_adios (rop, "RO-REJECT-P.INDICATION");
2501: ros_advise (rop, "RO-REJECT-P.INDICATION");
2502: }
2503:
2504: /* */
2505:
2506: /* ARGSUSED */
2507:
2508: static int ros_end (sd, roe)
2509: int sd;
2510: struct RoSAPend *roe;
2511: {
2512: if (isrts) {
2513: struct RtSAPindication rtis;
2514: register struct RtSAPindication *rti = &rtis;
2515: register struct RtSAPabort *rta = &rti -> rti_abort;
2516:
2517: advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
2518: if (RtEndResponse (sd, rti) == NOTOK)
2519: rts_adios (rta, "RT-END.RESPONSE");
2520: }
2521: else {
2522: struct RoSAPindication rois;
2523: register struct RoSAPindication *roi = &rois;
2524: register struct RoSAPpreject *rop = &roi -> roi_preject;
2525:
2526: advise (LLOG_NOTICE, NULLCP, "RO-END.INDICATION");
2527: if (RoEndResponse (sd, roi) == NOTOK)
2528: ros_adios (rop, "RO-END.RESPONSE");
2529: }
2530:
2531: exit (0);
2532: }
2533:
2534: /* */
2535:
2536: static int ros_finish (sd, acf)
2537: int sd;
2538: register struct AcSAPfinish *acf;
2539: {
2540: if (isrts) {
2541: struct RtSAPindication rtis;
2542: register struct RtSAPabort *rta = &rtis.rti_abort;
2543:
2544: advise (LLOG_NOTICE, NULLCP, "RT-CLOSE.INDICATION: %d, %d elements",
2545: acf -> acf_reason, acf -> acf_ninfo);
2546:
2547: if (RtCloseResponse (sd, ACR_NORMAL, mymode == echo
2548: ? acf -> acf_info[0] : NULLPE, &rtis) == NOTOK)
2549: rts_adios (rta, "RT-CLOSE.RESPONSE");
2550: }
2551: else {
2552: struct AcSAPindication acis;
2553: register struct AcSAPabort *aca = &acis.aci_abort;
2554:
2555: advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION: %d, %d elements",
2556: acf -> acf_reason, acf -> acf_ninfo);
2557:
2558: if (AcRelResponse (sd, ACS_ACCEPT, ACR_NORMAL, mymode == echo
2559: ? acf -> acf_info : NULLPEP, mymode == echo
2560: ? acf -> acf_ninfo : 0, &acis) == NOTOK)
2561: acs_adios (aca, "A-RELEASE.RESPONSE");
2562: }
2563:
2564: ACFFREE (acf);
2565:
2566: exit (0);
2567: }
2568:
2569: /* */
2570:
2571: static void ros_adios (rop, event)
2572: register struct RoSAPpreject *rop;
2573: char *event;
2574: {
2575: ros_advise (rop, event);
2576:
2577: _exit (1);
2578: }
2579:
2580:
2581: static void ros_advise (rop, event)
2582: register struct RoSAPpreject *rop;
2583: char *event;
2584: {
2585: char buffer[BUFSIZ];
2586:
2587: if (rop -> rop_cc > 0)
2588: (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
2589: rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
2590: else
2591: (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
2592:
2593: advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
2594: }
2595:
2596: /* ERRORS */
2597:
2598: #ifndef lint
2599: void adios (va_alist)
2600: va_dcl
2601: {
2602: va_list ap;
2603:
2604: va_start (ap);
2605:
2606: _ll_log (pgm_log, LLOG_FATAL, ap);
2607:
2608: va_end (ap);
2609:
2610: _exit (1);
2611: }
2612: #else
2613: /* VARARGS */
2614:
2615: void adios (what, fmt)
2616: char *what,
2617: *fmt;
2618: {
2619: adios (what, fmt);
2620: }
2621: #endif
2622:
2623:
2624: #ifndef lint
2625: void advise (va_alist)
2626: va_dcl
2627: {
2628: int code;
2629: va_list ap;
2630:
2631: va_start (ap);
2632:
2633: code = va_arg (ap, int);
2634:
2635: _ll_log (pgm_log, code, ap);
2636:
2637: va_end (ap);
2638: }
2639: #else
2640: /* VARARGS */
2641:
2642: void advise (code, what, fmt)
2643: char *what,
2644: *fmt;
2645: int code;
2646: {
2647: advise (code, what, fmt);
2648: }
2649: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.