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