|
|
1.1 root 1: /* ro2ssrespond.c - responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssrespond.c,v 7.1 90/07/01 21:05:56 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/rosap/RCS/ro2ssrespond.c,v 7.1 90/07/01 21:05:56 mrose Exp $
9: *
10: * Based on an TCP-based implementation by George Michaelson of University
11: * College London.
12: *
13: *
14: * $Log: ro2ssrespond.c,v $
15: * Revision 7.1 90/07/01 21:05:56 mrose
16: * pepsy
17: *
18: * Revision 6.0 89/03/18 23:42:19 mrose
19: * Release 5.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /* LINTLIBRARY */
35:
36: #include <stdio.h>
37: #include "../acsap/OACS-types.h"
38: #include "ropkt.h"
39: #include "tailor.h"
40:
41: /* RO-BEGIN.INDICATION */
42:
43: int RoInit (vecp, vec, ros, roi)
44: int vecp;
45: char **vec;
46: struct RoSAPstart *ros;
47: struct RoSAPindication *roi;
48: {
49: int result;
50: register struct assocblk *acb;
51: register PE pe;
52: struct SSAPref ref;
53: struct SSAPstart sss;
54: register struct SSAPstart *ss = &sss;
55: struct SSAPindication sis;
56: register struct SSAPindication *si = &sis;
57: register struct SSAPabort *sa = &si -> si_abort;
58: struct type_OACS_PConnect *pconn;
59:
60: isodetailor (NULLCP, 0);
61:
62: missingP (vec);
63: missingP (ros);
64: missingP (roi);
65:
66: if ((acb = newacblk ()) == NULL)
67: return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
68: acb -> acb_flags |= ACB_ROS;
69: (void) RoSService (acb, roi);
70:
71: if (SInit (vecp, vec, ss, si) == NOTOK) {
72: (void) ss2roslose (acb, roi, "SInit", sa);
73: goto out1;
74: }
75:
76: acb -> acb_fd = ss -> ss_sd;
77: acb -> acb_uabort = SUAbortRequest;
78:
79: acb -> acb_requirements = ss -> ss_requirements & SR_BCSUBSET;
80: if (acb -> acb_requirements & SR_DUPLEX)
81: acb -> acb_requirements = SR_DUPLEX;
82: else
83: if (acb -> acb_requirements & SR_HALFDUPLEX)
84: acb -> acb_requirements = SR_HALFDUPLEX;
85: else {
86: (void) rosaplose (roi, ROS_PROTOCOL, NULLCP,
87: "desired session requirements unavailable");
88: goto out2;
89: }
90:
91: if (acb -> acb_requirements & SR_HALFDUPLEX) {
92: if (((ss -> ss_settings >> ST_DAT_SHIFT) & ST_MASK) == ST_RESP_VALUE) {
93: acb -> acb_settings = ss -> ss_settings;
94: acb -> acb_flags |= ACB_TURN;
95: }
96: else {
97: acb -> acb_settings = ST_INIT_VALUE << ST_DAT_SHIFT;
98: acb -> acb_flags &= ~ACB_TURN;
99: }
100: }
101:
102: if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result))
103: == NULLPE) {
104: (void) rosaplose (roi, result != PS_ERR_NMEM ? ROS_PROTOCOL
105: : ROS_CONGEST, NULLCP, "%s", ps_error (result));
106: goto out2;
107: }
108:
109: SSFREE (ss);
110:
111: if (parse_OACS_PConnect (pe, 1, NULLIP, NULLVP, &pconn) == NOTOK) {
112: (void) pylose ();
113: pe_free (pe);
114: goto out2;
115: }
116:
117: PLOGP (rosap_log,OACS_PConnect, pe, "PConnect", 1);
118:
119: bzero ((char *) ros, sizeof *ros);
120: ros -> ros_sd = acb -> acb_fd;
121: ros -> ros_initiator.roa_addr = ss -> ss_calling; /* struct copy */
122: ros -> ros_port = htons ((u_short) pconn -> pUserData -> applicationProtocol);
123: if (pconn -> pUserData -> member_OACS_2 -> offset
124: == type_OACS_ConnectionData_open) {
125: ros -> ros_data = pe_expunge (pe, pconn -> pUserData
126: -> member_OACS_2 -> un.open);
127: } else
128: ros -> ros_data = NULLPE;
129:
130: free_OACS_PConnect (pconn);
131: return OK;
132:
133: out2: ;
134: bzero ((char *) &ref, sizeof ref);
135: (void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0,
136: SERIAL_NONE, NULLCP, 0, si);
137: acb -> acb_fd = NOTOK;
138:
139: out1: ;
140: SSFREE (ss);
141: freeacblk (acb);
142:
143: return NOTOK;
144: }
145:
146: /* RO-BEGIN.RESPONSE */
147:
148: int RoBeginResponse (sd, status, data, roi)
149: int sd;
150: int status;
151: PE data;
152: struct RoSAPindication *roi;
153: {
154: int len,
155: result;
156: char *base;
157: PE pe;
158: register struct assocblk *acb;
159: struct SSAPref ref;
160: struct SSAPindication sis;
161: register struct SSAPindication *si = &sis;
162: register struct SSAPabort *sa = &si -> si_abort;
163: struct type_OACS_PAccept paccpt;
164: struct type_OACS_DataTransferSyntax dts;
165: struct type_OACS_ConnectionData condata;
166: struct member_OACS_4 udata;
167:
168: if ((acb = findacblk (sd)) == NULL || (acb -> acb_flags & ACB_CONN))
169: return rosaplose (roi, ROS_PARAMETER, NULLCP,
170: "invalid association descriptor");
171: if (!(acb -> acb_flags & ACB_ROS))
172: return rosaplose (roi, ROS_PARAMETER, NULLCP,
173: "not an association descriptor for ROS");
174: switch (status) {
175: case ROS_ACCEPT:
176: break;
177:
178: case ROS_VALIDATE:
179: case ROS_BUSY:
180: if (data)
181: return rosaplose (roi, ROS_PARAMETER, NULLCP,
182: "user data not permitted when refusing association");
183: break;
184:
185: default:
186: return rosaplose (roi, ROS_PARAMETER, NULLCP,
187: "bad value for status parameter");
188: }
189: missingP (roi);
190:
191: bzero ((char *) &ref, sizeof ref); /* ECMA says don't encode this yet */
192:
193: base = NULLCP;
194: switch (status) {
195: case ROS_ACCEPT:
196: paccpt.member_OACS_3 = &dts;
197: dts.parm = int_OACS_DataTransferSyntax_x409;
198: paccpt.pUserData = &udata;
199: udata.checkpointSize = 0;
200: udata.windowsize = 3;
201: udata.member_OACS_5 = &condata;
202: condata.offset = type_OACS_ConnectionData_open;
203: if (data == NULLPE)
204: condata.un.open = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
205: PE_PRIM_NULL);
206: else
207: condata.un.open = data;
208:
209: if (encode_OACS_PAccept (&pe, 1, 0, NULLCP, &paccpt) == NOTOK) {
210: no_mem: ;
211: (void) rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
212: goto out1;
213: }
214: status = SC_ACCEPT;
215: break;
216:
217: default:
218: {
219: struct type_OACS_PRefuse prefuse;
220:
221: prefuse.parm = status;
222: if (encode_OACS_PRefuse(&pe, 1, 0, NULLCP, &prefuse) == NOTOK){
223: goto no_mem;
224: }
225: }
226: status = SC_REJECTED;
227: break;
228: }
229:
230: #ifdef DEBUG
231: if (rosap_log -> ll_events & LLOG_PDUS)
232: if (status == SC_ACCEPT)
233: pvpdu (rosap_log, print_OACS_PAccept_P, pe, "PAccept", 0);
234: else
235: pvpdu (rosap_log, print_OACS_PRefuse_P, pe, "PRefuse", 0);
236: #endif
237:
238: if (pe2ssdu (pe, &base, &len) == NOTOK)
239: goto no_mem;
240:
241: if (SConnResponse (acb -> acb_fd, &ref, NULLSA, status,
242: acb -> acb_requirements, acb -> acb_settings, SERIAL_NONE,
243: base, len, si) == NOTOK) {
244: acb -> acb_fd = NOTOK;
245: (void) ss2roslose (acb, roi, "SConnResponse", sa);
246: goto out3;
247: }
248:
249: if (status == SC_ACCEPT)
250: acb -> acb_flags |= ACB_CONN;
251: else {
252: acb -> acb_fd = NOTOK;
253: freeacblk (acb);
254: }
255: result = OK;
256:
257: out2: ;
258: if (pe) {
259: if (data)
260: (void) pe_extract (pe, data);
261: pe_free (pe);
262: }
263: if (base)
264: free (base);
265:
266: return result;
267:
268: out1: ;
269: (void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0,
270: SERIAL_NONE, NULLCP, 0, si);
271: acb -> acb_fd = NOTOK;
272: out3: ;
273: freeacblk (acb);
274: result = NOTOK;
275: goto out2;
276: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.