|
|
1.1 root 1: /* psaprelease1.c - PPM: initiate release */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprelease1.c,v 7.2 90/07/01 21:05:28 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap2-lpp/RCS/psaprelease1.c,v 7.2 90/07/01 21:05:28 mrose Exp $
9: *
10: * Contributed by The Wollongong Group, Inc.
11: *
12: *
13: * $Log: psaprelease1.c,v $
14: * Revision 7.2 90/07/01 21:05:28 mrose
15: * pepsy
16: *
17: * Revision 7.1 89/12/01 08:35:28 mrose
18: * touch-up
19: *
20: * Revision 7.0 89/11/23 22:15:56 mrose
21: * Release 6.0
22: *
23: */
24:
25: /*
26: * NOTICE
27: *
28: * Acquisition, use, and distribution of this module and related
29: * materials are subject to the restrictions of a license agreement.
30: * Consult the Preface in the User's Manual for the full terms of
31: * this agreement.
32: *
33: */
34:
35:
36: /* LINTLIBRARY */
37:
38: #include <stdio.h>
39: #include <signal.h>
40: #define LPP
41: #include "PS-types.h"
42: #include "ppkt.h"
43: #include "tailor.h"
44:
45: /* P-RELEASE.REQUEST */
46:
47: int PRelRequest (sd, data, ndata, secs, pr, pi)
48: int sd;
49: PE *data;
50: int ndata;
51: int secs;
52: struct PSAPrelease *pr;
53: struct PSAPindication *pi;
54: {
55: SBV smask;
56: int result;
57: register struct psapblk *pb;
58:
59: if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS)
60: return psaplose (pi, PC_PARAMETER, NULLCP, "bad release user data");
61: if (data[0] -> pe_context != PCI_ACSE)
62: return psaplose (pi, PC_PARAMETER, NULLCP,
63: "wrong context for release user data");
64: if (secs != NOTOK)
65: return psaplose (pi, PC_PARAMETER, NULLCP,
66: "asynchronous release not supported");
67: missingP (pr);
68: missingP (pi);
69:
70: smask = sigioblock ();
71:
72: psapPsig (pb, sd);
73:
74: if ((result = PRelRequestAux (pb, data[0], pr, pi)) == DONE)
75: result = OK;
76: else
77: freepblk (pb);
78:
79: (void) sigiomask (smask);
80:
81: return result;
82: }
83:
84: /* */
85:
86: static int PRelRequestAux (pb, data, pr, pi)
87: register struct psapblk *pb;
88: PE data;
89: struct PSAPrelease *pr;
90: struct PSAPindication *pi;
91: {
92: int result;
93: PE pe;
94: PS ps;
95: struct type_PS_PDUs *pdu;
96: register struct type_PS_ReleaseRequest__PDU *rr;
97:
98: pdu = NULL;
99: if ((rr = (struct type_PS_ReleaseRequest__PDU *) malloc (sizeof *rr))
100: == NULL) {
101: result = psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
102: goto out;
103: }
104: rr -> reference = pb -> pb_reliability == LOW_QUALITY ? pb -> pb_reference
105: : NULLRF;
106: rr -> user__data = data;
107:
108: result = encode_PS_ReleaseRequest__PDU (&pb -> pb_retry, 1, 0, NULLCP, rr);
109:
110: rr -> reference = NULL;
111: rr -> user__data = NULLPE;
112: free_PS_ReleaseRequest__PDU (rr);
113: rr = NULL;
114:
115: if (result == NOTOK) {
116: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s",
117: PY_pepy);
118: goto out;
119: }
120:
121: switch (pb -> pb_reliability) {
122: case HIGH_QUALITY:
123: default:
124: PLOGP (psap2_log,PS_PDUs, pb -> pb_retry,
125: "ReleaseRequest-PDU", 0);
126:
127: result = pe2ps (ps = pb -> pb_stream, pb -> pb_retry);
128:
129: pe_free (pb -> pb_retry);
130: pb -> pb_retry = NULLPE;
131:
132: if (result == NOTOK
133: || (pb -> pb_response = ps2pe (ps)) == NULLPE) {
134: result = pslose (pi, ps -> ps_errno);
135: goto out;
136: }
137: break;
138:
139: case LOW_QUALITY:
140: pb -> pb_tries = pb -> pb_maxtries;
141:
142: again: ;
143: for (;;) {
144: switch ((*pb -> pb_retryfnx) (pb, PC_SESSION, pi)) {
145: case NOTOK:
146: result = NOTOK;
147: goto out;
148:
149: case OK:
150: continue;
151:
152: case DONE:
153: default:
154: break;
155: }
156: break;
157: }
158:
159: pdu = NULL;
160: break;
161: }
162:
163: result = decode_PS_PDUs (pb -> pb_response, 1, NULLIP, NULLVP, &pdu);
164:
165: #ifdef DEBUG
166: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
167: pvpdu (psap2_log, print_PS_PDUs_P, pb -> pb_response, "PDU", 1);
168: #endif
169:
170: if (result == NOTOK) {
171: if (pb -> pb_reliability == LOW_QUALITY)
172: goto bad_ref;
173:
174: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP,
175: "error decoding PDU: %s", PY_pepy);
176: goto out;
177: }
178:
179: switch (pdu -> offset) {
180: case type_PS_PDUs_releaseResponse:
181: {
182: register struct type_PS_ReleaseResponse__PDU *rp =
183: pdu -> un.releaseResponse;
184:
185: if (pb -> pb_reliability == LOW_QUALITY
186: && refcmp (pb -> pb_reference, rp -> reference)) {
187: (void) ppktlose (pb, pi, PC_SESSION, rp -> reference,
188: NULLCP, "reference mismatch");
189:
190: bad_ref: ;
191: if (pdu)
192: free_PS_PDUs (pdu);
193: goto again;
194: }
195:
196: pe = rp -> user__data, rp -> user__data = NULLPE;
197:
198: pr -> pr_affirmative = 1;
199: (pr -> pr_info[0] = pe) -> pe_context = PCI_ACSE;
200: pr -> pr_ninfo = 1;
201:
202: result = OK;
203: }
204: break;
205:
206: case type_PS_PDUs_abort:
207: {
208: register struct PSAPabort *pa = &pi -> pi_abort;
209: register struct type_PS_Abort__PDU *ab = pdu -> un.abort;
210:
211: if (pb -> pb_reliability == LOW_QUALITY
212: && refcmp (pb -> pb_reference, ab -> reference))
213: goto bad_ref;
214:
215: if (ab -> reason) {
216: switch (ab -> reason -> parm) {
217: case int_PS_Abort__reason_reason__not__specified:
218: default:
219: result = PC_NOTSPECIFIED;
220: break;
221:
222: case int_PS_Abort__reason_unrecognized__ppdu:
223: case int_PS_Abort__reason_unexpected__ppdu:
224: case int_PS_Abort__reason_unrecognized__ppdu__parameter:
225: result = PC_UNRECOGNIZED
226: + (ab -> reason -> parm
227: - int_PS_Abort__reason_unrecognized__ppdu);
228: break;
229:
230: case int_PS_Abort__reason_invalid__ppdu__parameter:
231: result = PC_INVALID;
232: break;
233:
234: case int_PS_Abort__reason_reference__mismatch:
235: result = PC_SESSION;
236: break;
237: }
238: result = psaplose (pi, result, NULLCP, NULLCP);
239: break;
240: }
241: pe = ab -> user__data, ab -> user__data = NULLPE;
242:
243: pi -> pi_type = PI_ABORT;
244: bzero ((char *) pa, sizeof *pa);
245:
246: pa -> pa_peer = 1;
247: pa -> pa_reason = PC_ABORTED;
248: (pa -> pa_info[0] = pe) -> pe_context = PCI_ACSE;
249: pa -> pa_ninfo = 1;
250:
251: result = NOTOK;
252: }
253: break;
254:
255: default:
256: /* this works 'cause the "reference" is always the FIRST element */
257: result = ppktlose (pb, pi, PC_SESSION,
258: pdu -> un.connectResponse -> reference, NULLCP,
259: "unexpected PDU %d", pdu -> offset);
260: break;
261: }
262:
263: out: ;
264: if (pdu)
265: free_PS_PDUs (pdu);
266: if (rr)
267: free_PS_ReleaseRequest__PDU (rr);
268:
269: return result;
270: }
271:
272: /* */
273:
274: /* ARGSUSED */
275:
276: int PRelRetryRequest (sd, secs, pr, pi)
277: int sd;
278: int secs;
279: struct PSAPrelease *pr;
280: struct PSAPindication *pi;
281: {
282: return psaplose (pi, PC_OPERATION, "release not in progress");
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.