|
|
1.1 root 1: /* vtpm.c - VTPM: FSM */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/vt/RCS/vtpm.c,v 7.0 89/11/23 22:31:57 mrose Rel $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/vt/RCS/vtpm.c,v 7.0 89/11/23 22:31:57 mrose Rel $
9: *
10: *
11: * $Log: vtpm.c,v $
12: * Revision 7.0 89/11/23 22:31:57 mrose
13: * Release 6.0
14: *
15: */
16:
17: /*
18: * NOTICE
19: *
20: * Acquisition, use, and distribution of this module and related
21: * materials are subject to the restrictions of a license agreement.
22: * Consult the Preface in the User's Manual for the full terms of
23: * this agreement.
24: *
25: */
26:
27:
28: #include "vtpm.h"
29: #include "eventmsg.h"
30: #include "sector1.h"
31:
32: #undef PEPYPARM
33: #define PEPYPARM int *
34:
35: int cmode;
36: extern int sd; /*Session descriptor for this association*/
37: extern int debug;
38:
39: struct SSAPref sfs;
40: struct SSAPref *sf;
41: struct PSAPaddr *pa;
42: struct AcSAPconnect accs;
43: struct AcSAPconnect *acc;
44: struct AcSAPrelease acrs;
45: struct AcSAPrelease *acr;
46: struct AcSAPindication acis;
47: struct AcSAPindication *aci;
48: struct AcSAPabort *aca;
49: AEI aei;
50: OID ctx,
51: pci;
52:
53: struct AcSAPstart acss;
54: struct AcSAPstart *acs;
55: struct PSAPstart *ps;
56: struct PSAPindication pi;
57: struct PSAPdata px;
58: struct PSAPfinish *pf;
59:
60: /****************************************************************************/
61: /* GET EVENT - attempt to read a PDU from the presentation connection */
62: /* designated by "sd", determine */
63: /* which imcoming event has ocurred, */
64: /* and process the event with "do_event" */
65: /* */
66: /* A non-blocking read is done and OK is returned if there */
67: /* is nothing to read. */
68: /* */
69: /* PARAMETERS - */
70: /* FD - the presentation ID for the connection to read from */
71: /* */
72: /* PE - a pointer to the presentation element that is read */
73: /* (note that what is passed is a pointer to a pointer to */
74: /* data structure so that the address of the PE */
75: /* that is read can be returned in this parameter) */
76: /* */
77: /* RETURNS - the number of the incoming event associated with reading */
78: /* this PE from the network */
79: /****************************************************************************/
80:
81: int
82: get_event(dd, pe)
83: int dd;
84: PE *pe;
85: {
86: int result, event;
87: PE nullpe;
88:
89: result = PReadRequest(dd, &px, OK, &pi);
90: switch (result) {
91: case NOTOK:
92: if (debug)
93: advise(LLOG_EXCEPTIONS,NULLCP, "P-READ REQUEST returned NOTOK");
94: return(NOTOK);
95: case DONE:
96: if (pi.pi_type == PI_FINISH) {
97: pf = &pi.pi_finish;
98: event = RLQ;
99: nullpe = NULLPE;
100: pe = &nullpe;
101: }
102: else if(pi.pi_type == PI_SYNC)
103: {
104: return( pn_ind(dd, &pi.pi_sync)) ;
105: }
106: else
107: adios(NULLCP, "PReadRequest returned DONE, but event unknown (%d)",pi.pi_type);
108: break;
109: case OK:
110: if (px.px_ninfo > 1)
111: adios(NULLCP, "read more than one PE from network!\n");
112: pe = &(px.px_info[0]);
113:
114: /* we are assuming here that you can only get one PDU per P-DATA.
115: */
116: PLOG (vt_log, print_VT_PDUs, *pe, NULLCP, 1);
117: if ((*pe)->pe_class != PE_CLASS_CONT)
118: adios(NULLCP,"read pe of class %d", (*pe)->pe_class);
119: switch((*pe)->pe_id) {
120: case (ASQ_PDU):
121: {
122: if (debug)
123: advise(LLOG_DEBUG,NULLCP, "got ASQ_PDU");
124:
125: event = ASQ;
126: }
127: case ASR_PDU:
128: {
129: if (debug)
130: advise(LLOG_DEBUG,NULLCP, "got ASR_PDU");
131:
132: event = ASR;
133: }
134: case AUQ_PDU:
135: if (debug)
136: advise(LLOG_DEBUG,NULLCP, "got AUQ_PDU");
137: event = AUQ;
138: break;
139: case DAQ_PDU:
140: if (debug)
141: advise(LLOG_DEBUG,NULLCP, "got DAQ_PDU");
142: event = DAQ;
143: break;
144: case DLQ_PDU:
145: if (debug)
146: advise(LLOG_DEBUG,NULLCP, "got DLQ_PDU");
147:
148: event = DLQ;
149: break;
150:
151: case NDQ_PDU:
152: {
153: if (debug)
154: advise(LLOG_DEBUG,NULLCP, "got NDQ_PDU");
155:
156: event = NDQ_tr; /*See comment below*/
157:
158: /* We're supposed to find out if the NDQ contains an
159: update to a triggered control object or not to determine
160: what kind of event we have. Right now we'll assume that
161: we do have such an update in all cases. Note that this may
162: be a problem if we use quarantine delivery control in the
163: future.
164:
165: for each update, find out if the update is for a display object
166: or for a control object. if it's a control object get the name
167: of it and find out if it has a trigger
168:
169: */
170: break;
171: }
172:
173: case UDQ_PDU:
174: {
175: event = UDQ;
176: break;
177: }
178:
179: case HDQ_PDU:
180: {
181: if(debug) advise(LLOG_NOTICE,NULLCP,"Got HDQ");
182: event = HDQ;
183: break;
184: }
185:
186: case RLR_PDU:
187: event = RLR;
188: break;
189:
190: default:
191: adios(NULLCP,"unknown PDU type %d", (*pe)->pe_id);
192: }
193: }
194: return(do_event(event,*pe));
195: }
196:
197:
198:
199: #define SECTORS 6
200:
201: /* number of states in each sector */
202:
203: unsigned max_state[SECTORS] = { 0, 13, 0, 0, 0, 10};
204:
205: int (*s0[])() = {
206: NULL
207: };
208:
209: int (*s1[])() = {
210: s1_01, /* states in the first sector */
211: s1_02B,
212: s1_02S,
213: s1_03B,
214: s1_03S,
215: s1_10B,
216: s1_10N,
217: s1_10T,
218: s1_50B,
219: s1_51Q,
220: s1_51R,
221: s1_51N,
222: s1_51T
223: };
224:
225: int (*s2[])() = {
226: NULL
227: };
228:
229: int (*s3[])() = {
230: NULL
231: };
232:
233: int (*s4[])() = {
234: NULL
235: };
236:
237: int (*s5[])() = {
238: s5_400B,
239: s5_402B,
240: s5_420B,
241: s5_422B,
242: s5_40N,
243: s5_40T,
244: s5_42N,
245: s5_42T,
246: s5_61,
247: s5_62
248: };
249:
250: int ((**sectors[])()) = {s0, s1, s2, s3, s4, s5};
251:
252:
253: unsigned state = 0,
254: sector = 1;
255:
256: do_event(event, pe)
257: int event;
258: PE pe;
259: {
260: if (debug)
261: advise(LLOG_DEBUG,NULLCP,
262: "in do_event, sector is %d, state is %d, event is %d (%s)",
263: sector, state, event,
264: event >= 0
265: && event < sizeof eventname/sizeof eventname[0]
266: ? eventname[event] : "INVALID");
267: if (sector >= SECTORS || state >= max_state[sector])
268: return(NOTOK);
269: return(sectors[sector][state](event, pe));
270: }
271:
272: /* ARGSUSED */
273: pn_ind(dd, psync) /* sync indications */
274: int dd;
275: struct PSAPsync *psync;
276: {
277: switch(psync->pn_type)
278: {
279: case SN_MAJORIND:
280: advise(LLOG_DEBUG,NULLCP, "vt: got SN_MAJORIND");
281: break;
282: case SN_MAJORCNF:
283: advise(LLOG_DEBUG,NULLCP, "vt: got SN_MAJORCNF");
284: break;
285: case SN_MINORIND:
286: advise(LLOG_DEBUG,NULLCP, "vt: got SN_MINORIND");
287: break;
288: case SN_MINORCNF:
289: advise(LLOG_DEBUG,NULLCP, "vt: got SN_MINORCNF");
290: break;
291: case SN_RESETIND:
292: /* advise(LLOG_DEBUG,NULLCP, "vt: resetind: SN_RESETIND"); */
293: if(psync->pn_options != SYNC_RESTART)
294: adios(NULLCP,"resetind: bad options params");
295: if(psync->pn_ninfo > 0)
296: return( do_event(BKQ,psync->pn_info[0]));
297: else return( do_event(BKQ,NULLPE));
298: case SN_RESETCNF:
299: /* advise(LLOG_DEBUG,NULLCP, "vt: got SN_RESETCNF\n"); */
300: if(psync->pn_options != SYNC_RESTART)
301: adios(NULLCP,"resetind: bad options params");
302: if(psync->pn_ninfo > 0)
303: return( do_event(BKR,psync->pn_info[0]));
304: else return( do_event(BKR,NULLPE));
305: default:
306: adios(NULLCP,"received bad sync type");
307: }
308: PNFREE(psync);
309: return(NOTOK);
310: }
311:
312:
313:
314:
315: /*****************************************************************************/
316: /* P_DATA - send a PDU via PDataRequest */
317: /* */
318: /* RETURNS - OK or exits on error */
319: /* */
320: /* PARAMETERS - */
321: /* PDU - a PE containing the PDU to be sent */
322: /* */
323: /* CLASSIFICATION - utility function for VTPM (used only in processing */
324: /* outgoing events that are mapped to P_DATA) */
325: /* */
326: /*****************************************************************************/
327:
328: p_data(pdu)
329: PE pdu;
330: {
331:
332: PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
333:
334: if (PDataRequest(sd, &pdu, 1, &pi) != OK)
335: ps_adios (&pi.pi_abort, "P-DATA.REQUEST");
336: pe_free(pdu);
337: return(OK);
338: }
339:
340:
341: /****************************************************************************/
342: /* P_MAJOR_SYNC.REQUEST - send a PDU via PMajSyncRequest */
343: /* */
344: /* RETURNS - OK or exits on error */
345: /* */
346: /* PARAMETERS - */
347: /* PDU - a PE containing the PDU to be sent */
348: /* */
349: /* CLASSIFICATION - utility function for VTPM (used only in processing */
350: /* outgoing events that are mapped to P_MAJOR_SYNC.REQUEST) */
351: /* */
352: /****************************************************************************/
353:
354: p_maj_sync_req(pdu)
355: PE pdu;
356: {
357: long ssn;
358:
359: PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
360:
361: if (PMajSyncRequest(sd, &ssn, &pdu, 1, &pi) != OK)
362: ps_adios (&pi.pi_abort, "P-MAJOR-SYNC.REQUEST");
363: return(OK);
364: }
365:
366:
367: /****************************************************************************/
368: /* P_MAJOR_SYNC.RESPONSE - send a PDU via PMajSyncResponse */
369: /* */
370: /* RETURNS - OK or exits on error */
371: /* */
372: /* PARAMETERS - */
373: /* PDU - a PE containing the PDU to be sent */
374: /* */
375: /* CLASSIFICATION - utility function for VTPM (used only in processing */
376: /* outgoing events that are mapped to P_MAJOR_SYNC.RESPONSE)*/
377: /* */
378: /****************************************************************************/
379:
380: p_maj_sync_resp(pdu)
381: PE pdu;
382: {
383: PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
384:
385: if (PMajSyncResponse(sd, &pdu, 1, &pi) != OK)
386: ps_adios (&pi.pi_abort, "P-MAJOR-SYNC.RESPONSE");
387: return(OK);
388: }
389:
390:
391: /***************************************************************************/
392: /* P_TYPED_DATA - send a PDU via PTypedRequest */
393: /* */
394: /* RETURNS - OK or exits on error */
395: /* */
396: /* PARAMETERS - */
397: /* PDU - a PE containing the PDU to be sent */
398: /* */
399: /* CLASSIFICATION - utility function for VTPM (used only in processing */
400: /* outgoing events that are mapped to P_TYPED_DATA) */
401: /* */
402: /***************************************************************************/
403:
404: p_typed_data(pdu)
405: PE pdu;
406: {
407:
408: PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
409:
410: if (PTypedRequest(sd, &pdu, 1, &pi) != OK)
411: ps_adios (&pi.pi_abort, "P-TYPED-DATA.REQUEST");
412: return(OK);
413: }
414:
415: /*****************************************************************************/
416: /* P_RESYNCHRONIZE.REQUEST - send a PDU via PReSyncRequest */
417: /* */
418: /* RETURNS - OK or exits on error */
419: /* */
420: /* PARAMETERS - */
421: /* PDU - a PE containing the (break) PDU to be sent */
422: /* */
423: /* CLASSIFICATION - utility function for VTPM (used only in processing */
424: /* outgoing events that are mapped to P_RESYNC.REQUEST) */
425: /*****************************************************************************/
426:
427: p_resync_req(pdu,type)
428: PE pdu;
429: int type;
430: {
431:
432: long ssn = 0; /* should be made a global at some time */
433: int settings = ST_INIT_VALUE;
434:
435: #define VTKP_REQ 0x00 /* setting values, see ssap.h */
436: #define VTKP_ACC 0x15
437: #define VTKP_CHO 0x2a
438:
439: PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
440:
441: if (PReSyncRequest(sd, type, ssn, settings, &pdu, 1, &pi) != OK)
442: /* if (PReSyncRequest(sd, type, 0, 0, (PE *)NULL, 0, &pi) != OK) */
443: ps_adios (&pi.pi_abort, "P-RESYNCHRONIZE.REQUEST");
444: return(OK);
445: }
446:
447:
448: /****************************************************************************/
449: /* P_RESYNC.RESPONSE - send a PDU via PReSyncResponse */
450: /* */
451: /* RETURNS - OK or exits on error */
452: /* */
453: /* PARAMETERS - */
454: /* PDU - a PE containing the PDU to be sent */
455: /* */
456: /* CLASSIFICATION - utility function for VTPM (used only in processing */
457: /* outgoing events that are mapped to P_RESYNC.RESPONSE) */
458: /* */
459: /****************************************************************************/
460:
461: p_resync_resp(pdu)
462: PE pdu;
463: {
464:
465: long ssn = 0; /* should be made a global at some time */
466: int settings = ST_INIT_VALUE;
467: PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
468:
469: if (PReSyncResponse(sd, ssn, settings, &pdu, 1, &pi) != OK)
470: ps_adios (&pi.pi_abort, "P-RESYNCHRONIZE.RESPONSE");
471: return(OK);
472: }
473:
474:
475:
476: /****************************************************************************/
477: /* ASR - generate an ASR event. (that is send an ASR PDU which is */
478: /* passed in as a parameter as user data on the AcAssocResponse.)*/
479: /* */
480: /* PARAMETERS: PE - a vt ASR PDU */
481: /* status (SUCCESS or FAILURE) */
482: /* */
483: /* RETURNS: OK */
484: /****************************************************************************/
485:
486: asr(pe,status)
487: PE pe;
488: int status;
489: {
490:
491: /* include "pe" as user data on the AcAssocResponse
492: */
493: struct PSAPctxlist *pl = &ps->ps_ctxlist;
494: int s_requirements;
495: long isn;
496: int reason, i;
497:
498: if (debug > 2) {
499: for(i=0; i<pl->pc_nctx; i++)
500: advise(LLOG_DEBUG,NULLCP," ctx %d: %d %s %d",
501: i,pl->pc_ctx[i].pc_id,sprintoid(pl->pc_ctx[i].pc_asn),
502: pl->pc_ctx[i].pc_result);
503:
504: }
505: if (debug) {
506: advise(LLOG_DEBUG,NULLCP, "in asr.\n");
507: advise(LLOG_DEBUG,NULLCP, "about to call AcAssocResp, sd is %d, pe->pe_id is %d\n", sd, pe->pe_id);
508: }
509:
510: if(status == SUCCESS)
511: {
512: status = ACS_ACCEPT;
513: reason = ACS_USER_NULL;
514: }
515: else
516: {
517: status = ACS_PERMANENT;
518: reason = ACS_USER_NOREASON;
519: }
520: s_requirements = SR_DUPLEX | SR_RESYNC | SR_TYPEDATA;
521: isn = 0;
522: pe -> pe_context = 1;
523: if (AcAssocResponse (sd, status, reason, NULLOID, NULLAEI,
524: NULLPA,
525: &ps->ps_ctxlist,
526: ps->ps_defctxresult, ps->ps_prequirements, s_requirements,isn,
527: ps->ps_settings, &ps->ps_connect, &pe, 1, aci) == NOTOK)
528: acs_adios (aca, "A-ASSOCIATE.RESPONSE");
529:
530: if (debug)
531: advise(LLOG_DEBUG,NULLCP, "sent AcAssociate Response\n");
532: return(OK);
533: }
534:
535:
536:
537: send_bad_asr(reason) /*Compose and send ASR with result = failure. Encode
538: ASR-FailureReason using the reason parameter
539: (0 means no reason).
540: */
541:
542: int reason;
543: {
544:
545: PE asr_pe;
546: ASR_MSG ud;
547:
548: bzero ((char *) &ud, sizeof ud);
549: if(reason)
550: {
551: ud.valid_reason = 1;
552: ud.reason.type = 1;
553: ud.reason.provider_reason = reason;
554: }
555: else ud.valid_reason = 0;
556: ud.result = 0; /*Failure code*/
557: ud.valid_imp = 0;
558: ud.valid_coll = 0;
559: ud.valid_arg_list = 0;
560: ud.version.bitstring = 0x00;
561: ud.version.bitcount = 5;
562: if(build_ASRPDU_ASRpdu(&asr_pe,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
563: adios (NULLCP, "ASR build failure (%s)", PY_pepy);
564:
565: return(asr(asr_pe,FAILURE)); /*Send the PDU thru Association control*/
566: }
567:
568:
569: send_rlr(pe) /*Send RLR (Release Response) PDU to peer. The RLR is
570: built by vrelrsp(). It is sent by a call to Association
571: Control.
572: */
573: PE pe;
574: {
575: pe -> pe_context = 1;
576: if(AcRelResponse(sd,ACS_ACCEPT,ACR_NORMAL,&pe,1,aci) == NOTOK)
577: acs_adios (&aci->aci_abort, "A-RELEASE.RESPONSE");
578: }
579:
580:
581: clear_vte() /*Clear VT Environment. */
582: {
583:
584: /*Nothing to do for now since we have no formalized environment
585: and we exit VTP when association ends.
586: */
587: }
588:
589:
590: vgvt_ind() /*Indication to User that peer has given the token*/
591: {
592:
593: /*Don't know how to indicate this to user yet*/
594: }
595:
596:
597: vrtq_ind() /*Indicate to User that peer has requested token*/
598: {
599:
600: /*Don't know how to give indication to user.
601: Synchronous? Asynch interrupt??? */
602: }
603:
604:
605: give_token() /*Transfer Token to peer. For VTP, all tokens are given
606: at once so no need to discriminate between them.
607: */
608: {
609:
610: int vt_tokens;
611: struct PSAPindication vt_pi;
612:
613: vt_tokens = ST_RLS_TOKEN;
614:
615: if(PGTokenRequest(sd,vt_tokens,&vt_pi) == NOTOK
616: && vt_pi.pi_abort.pa_reason != PC_OPERATION)
617: ps_adios (&vt_pi.pi_abort, "P-GIVE-TOKENS.REQUEST");
618: }
619:
620:
621: request_token() /*Request Tokens from peer*/
622: {
623:
624: int vt_tokens;
625: struct PSAPindication vt_pi;
626:
627: vt_tokens = ST_RLS_TOKEN;
628:
629: if(PPTokenRequest(sd,vt_tokens,NULLPEP,0,&vt_pi) == NOTOK
630: && vt_pi.pi_abort.pa_reason != PC_OPERATION)
631: ps_adios (&vt_pi.pi_abort, "P-PLEASE-TOKENS.REQUEST");
632: }
633:
634: send_all() /*TEMP -- Should be supplied by Sector 5 actions*/
635: {
636: advise(LLOG_DEBUG,NULLCP, "send_all dummy routine");
637: }
638:
639: /* */
640:
641: void acs_adios (aa, event)
642: register struct AcSAPabort *aa;
643: char *event;
644: {
645: acs_advise (aa, event);
646:
647: finalbye ();
648:
649: _exit (1);
650: }
651:
652:
653: static void acs_advise (aa, event)
654: register struct AcSAPabort *aa;
655: char *event;
656: {
657: char buffer[BUFSIZ];
658:
659: if (aa -> aca_cc > 0)
660: (void) sprintf (buffer, "[%s] %*.*s",
661: AcErrString (aa -> aca_reason),
662: aa -> aca_cc, aa -> aca_cc, aa -> aca_data);
663: else
664: (void) sprintf (buffer, "[%s]", AcErrString (aa -> aca_reason));
665:
666: advise (LLOG_NOTICE,NULLCP, "%s: %s (source %d)", event, buffer,
667: aa -> aca_source);
668: }
669:
670:
671: static void ps_adios (pab, event)
672: register struct PSAPabort *pab;
673: char *event;
674: {
675: ps_advise (pab, event);
676:
677: finalbye ();
678:
679: _exit (1);
680: }
681:
682:
683: static void ps_advise (pab, event)
684: register struct PSAPabort *pab;
685: char *event;
686: {
687: char buffer[BUFSIZ];
688:
689: if (pab -> pa_cc > 0)
690: (void) sprintf (buffer, "[%s] %*.*s",
691: PErrString (pab -> pa_reason),
692: pab -> pa_cc, pab -> pa_cc, pab -> pa_data);
693: else
694: (void) sprintf (buffer, "[%s]", PErrString (pab -> pa_reason));
695:
696: advise (LLOG_NOTICE,NULLCP, "%s: %s%s", event, buffer,
697: pab -> pa_peer ? " (peer initiated)" : "");
698: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.